diff --git a/css/geolocation-widget-googlegeocoder.css b/css/geolocation-widget-googlegeocoder.css
index 9351c8f..5db86a7 100644
--- a/css/geolocation-widget-googlegeocoder.css
+++ b/css/geolocation-widget-googlegeocoder.css
@@ -19,15 +19,15 @@
   max-width: none;
 }
 
-.geocode-controlls-wrapper {
+.geocode-controls-wrapper {
   display: block;
   width: 100%;
   font-size: 14px;
   margin: 1em 0 0 1em;
 }
 
-.geocode-controlls-wrapper input,
-.geocode-controlls-wrapper button {
+.geocode-controls-wrapper input,
+.geocode-controls-wrapper button {
   position: relative;
   padding: 0;
   font-size: inherit;
@@ -45,7 +45,7 @@
   appearance: none;
 }
 
-.geocode-controlls-wrapper input {
+.geocode-controls-wrapper input {
   padding: 0 1em;
   border-radius: 2px 0 0 2px;
   background-color: #fff;
@@ -53,11 +53,11 @@
   max-width: 350px;
   z-index: 3;
 }
-.geocode-controlls-wrapper input:focus {
+.geocode-controls-wrapper input:focus {
   border-color: #4d90fe;
 }
 
-.geocode-controlls-wrapper button {
+.geocode-controls-wrapper button {
   color: #FFF;
   cursor: pointer;
   height: 32px;
@@ -65,7 +65,7 @@
   z-index: 2;
 }
 
-.geocode-controlls-wrapper .geolocation-map-indicator {
+.geocode-controls-wrapper .geolocation-map-indicator {
   z-index: 1;
   position: relative;
   background-color: rgba(174, 213, 129, 0.75);
@@ -81,7 +81,7 @@
   top: -20px;
   color: rgb(255,255,255);
 }
-.geocode-controlls-wrapper .geolocation-map-indicator.has-location {
+.geocode-controls-wrapper .geolocation-map-indicator.has-location {
   top: 0px;
   box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.3);
 }
diff --git a/geolocation.libraries.yml b/geolocation.libraries.yml
index 28173e3..a3edbf2 100644
--- a/geolocation.libraries.yml
+++ b/geolocation.libraries.yml
@@ -8,6 +8,15 @@ geolocation.core:
     - core/drupalSettings
   js:
     js/geolocation.js: {}
+
+# Google maps geocoder function.
+geolocation.geocoder:
+  version: 8.x-1.x
+  js:
+    js/geolocation-geocoder.js: {}
+  dependencies:
+    - geolocation/geolocation.core
+
 # Google maps display formatter.
 geolocation.maps:
   version: 8.x-1.x
@@ -15,6 +24,7 @@ geolocation.maps:
     js/geolocation-formatter-googlemap.js: {}
   dependencies:
     - geolocation/geolocation.core
+
 # Google geocoder widget library.
 geolocation.widgets.googlegeocoder:
   version: 1.x
@@ -24,7 +34,8 @@ geolocation.widgets.googlegeocoder:
   js:
     js/geolocation-widget-googlegeocoder.js: { scope: footer }
   dependencies:
-    - geolocation/geolocation.core
+    - geolocation/geolocation.geocoder
+
 # HTML5 widget library.
 geolocation.widgets.html5:
   version: 1.x
@@ -35,6 +46,7 @@ geolocation.widgets.html5:
     js/geolocation-widget-html5.js: { scope: footer }
   dependencies:
     - geolocation/geolocation.core
+
 # CommonMap widget library.
 geolocation.commonmap:
   css:
diff --git a/js/geolocation-formatter-googlemap.js b/js/geolocation-formatter-googlemap.js
index 1bfefb9..59bd426 100644
--- a/js/geolocation-formatter-googlemap.js
+++ b/js/geolocation-formatter-googlemap.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * Javascript for the geocoder Google map formatter.
+ * Javascript for the Google map formatter.
  */
 (function ($, Drupal) {
 
diff --git a/js/geolocation-geocoder.js b/js/geolocation-geocoder.js
new file mode 100644
index 0000000..804cae6
--- /dev/null
+++ b/js/geolocation-geocoder.js
@@ -0,0 +1,132 @@
+/**
+ * @file
+ *   Javascript for the Google geocoder function.
+ */
+
+(function ($, Drupal, _) {
+  'use strict';
+
+  /* global google */
+
+  /**
+   * @namespace
+   */
+  Drupal.geolocation = Drupal.geolocation || {};
+  Drupal.geolocation.geocoder = Drupal.geolocation.geocoder || {};
+
+  /**
+   * Load google maps and set a callback to run when it's ready.
+   *
+   * @param {object} map - The Google Map object
+   */
+  Drupal.geolocation.geocoder.add = function (map) {
+
+    /**
+     * Callback for geocoder controls click submit.
+     *
+     * @param {object} e - The event from input keypress or the click of the submit button.
+     */
+    var handleControlEvent = function (e) {
+      if (typeof e.keyCode === 'undefined' || e.keyCode === 13 || e.keyCode === 0) {
+        // We don't any forms submitting.
+        e.preventDefault();
+        // Get the address from the input value.
+        var address = $(e.target).parent().children('input.input').val();
+        // Make sure there are at least 2 characters for geocoding.
+        if (address.length > 1) {
+          // Run the geocode function with google maps.
+          map.geocoder.geocode({address: address}, function (results, status) {
+            if (status === google.maps.GeocoderStatus.OK) {
+              // Set the map viewport.
+              map.googleMap.fitBounds(results[0].geometry.viewport);
+              // Set the map marker.
+              Drupal.geolocation.setMapMarker(results[0].geometry.location, map);
+
+              Drupal.geolocation.geocoder.resultCallback(results[0]);
+            }
+            else {
+              // Alert of the error geocoding.
+              alert(Drupal.t('Geocode was not successful for the following reason: ') + status);
+            }
+          });
+        }
+      }
+    };
+
+    map.geocoder = new google.maps.Geocoder();
+    map.controls = $('<div class="geocode-controls-wrapper" />')
+      .append($('<input type="text" class="input" placeholder="Enter a location" />'))
+      // Create submit button
+      .append($('<button class="submit" />'))
+      // Create clear button
+      .append($('<button class="clear" />'))
+      // Create clear button
+      .append($('<div class="geolocation-map-indicator" />'))
+      // Use the DOM element.
+      .get(0);
+
+    // Add the default indicator if the values aren't blank.
+    if (map.lat !== '' && map.lng !== '') {
+      $(map.controls).children('.geolocation-map-indicator')
+        .addClass('has-location')
+        .text(map.lat + ', ' + map.lng);
+    }
+
+    map.controls.index = 1;
+
+    map.googleMap.controls[google.maps.ControlPosition.TOP_LEFT].push(map.controls);
+
+    google.maps.event.addDomListener($(map.controls).children('button.submit')[0], 'click', handleControlEvent);
+    google.maps.event.addDomListener($(map.controls).children('input.input')[0], 'keyup', handleControlEvent);
+    google.maps.event.addDomListener($(map.controls).children('button.clear')[0], 'click', function (e) {
+      // Stop all that bubbling and form submitting.
+      e.preventDefault();
+      // Remove the coordinates.
+      $(map.controls).children('.geolocation-map-indicator').text('').removeClass('has-location');
+      // Clear the map point.
+      map.marker.setMap();
+      // Clear the input text.
+      $(map.controls).children('input.input').val('');
+    });
+  };
+
+  /**
+   * Provides the callback that is called when geocoded results are found loads.
+   *
+   * @param {object} result - first returned address
+   */
+  Drupal.geolocation.geocoder.resultCallback = function (result) {
+    // Ensure callbacks array;
+    Drupal.geolocation.geocoder.resultCallbacks = Drupal.geolocation.geocoder.resultCallbacks || [];
+    _.invoke(Drupal.geolocation.geocoder.resultCallbacks, 'callback', result);
+  };
+
+  /**
+   * Adds a callback that will be called when results are found.
+   *
+   * @param {geolocationCallback} callback - The callback
+   * @param {string} [id] - Identify the callback
+   */
+  Drupal.geolocation.geocoder.addResultCallback = function (callback, id) {
+    if (typeof id === 'undefined') {
+      id = 'none';
+    }
+    Drupal.geolocation.geocoder.resultCallbacks = Drupal.geolocation.geocoder.resultCallbacks || [];
+    Drupal.geolocation.geocoder.resultCallbacks.push({callback: callback, id: id});
+  };
+
+  /**
+   * Remove a callback that will be called when results are found.
+   *
+   * @param {string} id - Identify the callback
+   */
+  Drupal.geolocation.geocoder.removeResultCallback = function (id) {
+    Drupal.geolocation.geocoder.resultCallbacks = Drupal.geolocation.geocoder.resultCallbacks || [];
+    $.each(Drupal.geolocation.geocoder.resultCallbacks, function (index, callback) {
+      if (callback.id !== 'none' && callback.id === id) {
+        Drupal.geolocation.geocoder.resultCallbacks.splice(index, 1);
+      }
+    });
+  };
+
+})(jQuery, Drupal, _);
diff --git a/js/geolocation-widget-googlegeocoder.js b/js/geolocation-widget-googlegeocoder.js
index 11b55c6..1247adc 100644
--- a/js/geolocation-widget-googlegeocoder.js
+++ b/js/geolocation-widget-googlegeocoder.js
@@ -12,6 +12,7 @@
    * @namespace
    */
   Drupal.geolocation = Drupal.geolocation || {};
+  Drupal.geolocation.geocoderWidget = Drupal.geolocation.geocoderWidget || {};
 
   /**
    * Attach geocoder functionality.
@@ -21,16 +22,16 @@
    * @prop {Drupal~behaviorAttach} attach
    *   Attaches geocoder functionality to relevant elements.
    */
-  Drupal.behaviors.geolocationGooglemaps = {
+  Drupal.behaviors.geolocationGeocoderWidget = {
     attach: function (context, settings) {
       // Ensure iterables.
-      settings.geolocation = settings.geolocation || {widget_maps: []};
+      settings.geolocation = settings.geolocation || {widgetMaps: []};
       // Make sure the lazy loader is available.
       if (typeof Drupal.geolocation.loadGoogle === 'function') {
         // First load the library from google.
         Drupal.geolocation.loadGoogle(function () {
           // This won't fire until window load.
-          initialize(settings.geolocation.widget_maps);
+          initialize(settings.geolocation.widgetMaps, context);
         });
       }
     }
@@ -41,34 +42,33 @@
    *
    * @param {object} map - The current map object.
    */
-  Drupal.geolocation.addClickListener = function (map) {
+  Drupal.geolocation.geocoderWidget.addClickListener = function (map) {
     // Used for a single click timeout.
     var singleClick;
     // Add the click listener.
+    /**
+     * @param {{latLng:object}} e
+     */
     google.maps.event.addListener(map.googleMap, 'click', function (e) {
       // Create 500ms timeout to wait for double click.
       singleClick = setTimeout(function () {
-        Drupal.geolocation.codeLatLng(e.latLng, map);
+        Drupal.geolocation.setHiddenInputFields(e.latLng, map);
         Drupal.geolocation.setMapMarker(e.latLng, map);
       }, 500);
     });
+
     // Add a doubleclick listener.
     google.maps.event.addListener(map.googleMap, 'dblclick', function (e) {
       clearTimeout(singleClick);
     });
   };
 
-  /**
-   * Runs after the google maps api is available
-   *
-   * @param {object} maps - The google map object.
-   */
-  function initialize(maps) {
+  function initialize(maps, context) {
     // Process drupalSettings for every Google map present on the current page.
     $.each(maps, function (widget_id, map) {
 
       // Get the container object.
-      map.container = document.getElementById(map.id);
+      map.container = $('#' + map.id, context).first();
 
       if ($(map.container).length >= 1
         && !$(map.container).hasClass('geolocation-processed')
@@ -88,10 +88,101 @@
         Drupal.geolocation.addMap(map);
 
         // Add the geocoder to the map.
-        Drupal.geolocation.addGeocoder(map);
+        Drupal.geolocation.geocoder.add(map);
+
+        Drupal.geolocation.geocoder.addResultCallback(function (address) {
+          Drupal.geolocation.geocoderWidget.setHiddenInputFields(address.geometry.location, map);
+        });
+
+        if (typeof drupalSettings.geolocation.widgetSettings.addressFieldTarget !== 'undefined') {
+          var targetField = drupalSettings.geolocation.widgetSettings.addressFieldTarget;
+
+          Drupal.geolocation.geocoder.addResultCallback(function (address) {
+            var addressField = $('.field--type-address.field--widget-address-default.field--name-' + targetField.replace(/_/g, '-'), context);
+
+            var addressLine1 = '';
+            var addressLine2 = '';
+            var postalTown = '';
+            var countryCode = null;
+            var postalCode = null;
+            var streetNumber = null;
+            var premise = null;
+            var route = null;
+            var locality = null;
+            var administrativeArea = null;
+
+            $.each(address.address_components, function (key, value) {
+              var component = address.address_components[key];
+              var types = component.types;
+
+              switch (types[0]) {
+                case 'country':
+                  countryCode = component.short_name;
+                  break;
+                case 'postal_town':
+                  postalTown = component.long_name;
+                  break;
+                case 'postal_code':
+                  postalCode = component.long_name;
+                  break;
+                case 'street_number':
+                  streetNumber = component.long_name;
+                  break;
+                case 'premise':
+                  premise = component.long_name;
+                  break;
+                case 'route':
+                  route = component.long_name;
+                  break;
+                case 'locality':
+                  locality = component.long_name;
+                  break;
+                case 'administrative_area_level_1':
+                  administrativeArea = component.short_name;
+                  break;
+              }
+            });
+
+            if (addressField.length === 0) {
+              // TODO: Widget is hidden. Store values now in form and save them in Drupal later.
+            }
+            else {
+              // Set the country.
+              addressField.find('.country.form-select').val(countryCode).trigger('change');
+
+              if (streetNumber) {
+                addressLine1 = streetNumber + ' ' + route;
+              }
+              else {
+                addressLine1 = route;
+              }
+
+              if (!!locality && locality !== postalTown) {
+                addressLine2 = locality;
+              }
+
+              $(document).ajaxComplete(function (event, xhr, settings) {
+                if (settings.extraData._drupal_ajax && settings.extraData._triggering_element_name === targetField + '[0][country_code]') {
+                  var addressDetails = addressField.find('.details-wrapper').first();
+                  // Populate the address fields, once they have been added to the DOM.
+                  addressDetails.find('.organization').val(premise);
+                  addressDetails.find('.address-line1').val(addressLine1);
+                  addressDetails.find('.address-line2').val(addressLine2);
+                  addressDetails.find('.locality').val(locality);
+                  addressDetails.find('.administrative-area').val(countryCode + '-' + administrativeArea);
+                  addressDetails.find('.postal-code').val(postalCode);
+                }
+              });
+            }
+          });
+        }
+
+        google.maps.event.addDomListener($(map.controls).children('button.clear')[0], 'click', function (e) {
+          Drupal.geolocation.geocoderWidget.clearHiddenInputFields(map);
+        });
 
         // Add the click responders for setting the value.
-        Drupal.geolocation.addClickListener(map);
+        Drupal.geolocation.geocoderWidget.addClickListener(map);
 
         // Set the already processed flag.
         $(map.container).addClass('geolocation-processed');
@@ -99,4 +190,28 @@
     });
   }
 
+  /**
+   * Set the latitude and longitude values to the input fields
+   *
+   * @param {object} latLng - A location (latLng) object from google maps API.
+   * @param {object} map - The settings object that contains all of the necessary metadata for this map.
+   */
+  Drupal.geolocation.geocoderWidget.setHiddenInputFields = function (latLng, map) {
+    // Update the lat and lng input fields.
+    $('fieldset.canvas-' + map.id + ' .geolocation-hidden-lat').attr('value', latLng.lat());
+    $('fieldset.canvas-' + map.id + ' .geolocation-hidden-lng').attr('value', latLng.lng());
+  };
+
+  /**
+   * Set the latitude and longitude values to the input fields
+   *
+   * @param {object} map - The settings object that contains all of the necessary metadata for this map.
+   */
+  Drupal.geolocation.geocoderWidget.clearHiddenInputFields = function (map) {
+    // Update the lat and lng input fields.
+    $('fieldset.canvas-' + map.id + ' .geolocation-hidden-lat').attr('value', '');
+    $('fieldset.canvas-' + map.id + ' .geolocation-hidden-lng').attr('value', '');
+  };
+
+
 })(jQuery, Drupal, drupalSettings);
diff --git a/js/geolocation.js b/js/geolocation.js
index 1e4a58c..4499ef5 100644
--- a/js/geolocation.js
+++ b/js/geolocation.js
@@ -1,7 +1,8 @@
 /**
  * @file
- *   Javascript for the geocoder module.
+ *   Javascript for the geolocation module.
  */
+
 (function ($, _, Drupal, drupalSettings) {
 
   'use strict';
@@ -53,12 +54,12 @@
    */
   Drupal.geolocation.googleCallback = function () {
     // Ensure callbacks array;
-    Drupal.geolocation.google_load_callbacks = Drupal.geolocation.google_load_callbacks || [];
+    Drupal.geolocation.googleCallbacks = Drupal.geolocation.googleCallbacks || [];
 
     // Wait until the window load event to try to use the maps library.
     $(document).ready(function (e) {
-      _.invoke(drupalSettings.geolocation.google_load_callbacks, 'callback');
-      Drupal.geolocation.google_load_callbacks = [];
+      _.invoke(Drupal.geolocation.googleCallbacks, 'callback');
+      Drupal.geolocation.googleCallbacks = [];
     });
   };
 
@@ -68,8 +69,8 @@
    * @param {geolocationCallback} callback - The callback
    */
   Drupal.geolocation.addCallback = function (callback) {
-    drupalSettings.geolocation.google_load_callbacks = Drupal.geolocation.google_load_callbacks || [];
-    drupalSettings.geolocation.google_load_callbacks.push({callback: callback});
+    Drupal.geolocation.googleCallbacks = Drupal.geolocation.googleCallbacks || [];
+    Drupal.geolocation.googleCallbacks.push({callback: callback});
   };
 
   /**
@@ -153,101 +154,6 @@
   };
 
   /**
-   * Load google maps and set a callback to run when it's ready.
-   *
-   * @param {object} map - The Google Map object
-   */
-  Drupal.geolocation.addGeocoder = function (map) {
-
-    /**
-     * Callback for geocoder controls click submit.
-     *
-     * @param {object} e - The event from input keypress or the click of the submit button.
-     */
-    var handleControlEvent = function (e) {
-      if (typeof e.keyCode === 'undefined' || e.keyCode === 13 || e.keyCode === 0) {
-        // We don't any forms submitting.
-        e.preventDefault();
-        // Get the address from the input value.
-        var address = $(e.target).parent().children('input.input').val();
-        // Make sure there are at least 2 characters for geocoding.
-        if (address.length > 1) {
-          // Run the geocode function with google maps.
-          map.geocoder.geocode({address: address}, function (results, status) {
-            if (status === google.maps.GeocoderStatus.OK) {
-              // Set the map viewport.
-              map.googleMap.fitBounds(results[0].geometry.viewport);
-              // Set the values for the field.
-              Drupal.geolocation.codeLatLng(results[0].geometry.location, map);
-              // Set the map marker.
-              Drupal.geolocation.setMapMarker(results[0].geometry.location, map);
-            }
-            else {
-              // Alert of the error geocoding.
-              alert(Drupal.t('Geocode was not successful for the following reason: ') + status);
-            }
-          });
-        }
-      }
-    };
-
-    map.geocoder = new google.maps.Geocoder();
-    map.controls = $('<div class="geocode-controlls-wrapper" />')
-      .append($('<input type="text" class="input" placeholder="Enter a location" />'))
-      // Create submit button
-      .append($('<button class="submit" />'))
-      // Create clear button
-      .append($('<button class="clear" />'))
-      // Create clear button
-      .append($('<div class="geolocation-map-indicator" />'))
-      // Use the DOM element.
-      .get(0);
-
-    // Add the default indicator if the values aren't blank.
-    if (map.lat !== '' && map.lng !== '') {
-      $(map.controls).children('.geolocation-map-indicator')
-        .addClass('has-location')
-        .text(map.lat + ', ' + map.lng);
-    }
-
-    map.controls.index = 1;
-
-    map.googleMap.controls[google.maps.ControlPosition.TOP_LEFT].push(map.controls);
-
-    // Add the listened for the search click event.
-    google.maps.event.addDomListener($(map.controls).children('button.submit')[0], 'click', handleControlEvent);
-    // Add the listened for the search click event.
-    google.maps.event.addDomListener($(map.controls).children('input.input')[0], 'keyup', handleControlEvent);
-    // Add the event listener for the remove button.
-    google.maps.event.addDomListener($(map.controls).children('button.clear')[0], 'click', function (e) {
-      // Stop all that bubbling and form submitting.
-      e.preventDefault();
-      // Remove the coordinates.
-      $(map.controls).children('.geolocation-map-indicator').text('').removeClass('has-location');
-      // Clear the map point.
-      map.marker.setMap();
-      // Clear the input text.
-      $(map.controls).children('input.input').val('');
-      // Remove the form values.
-      // Update the lat and lng input fields
-      $('.geolocation-hidden-lat.for-' + map.id).attr('value', '');
-      $('.geolocation-hidden-lng.for-' + map.id).attr('value', '');
-    });
-  };
-
-  /**
-   * Set the latitude and longitude values to the input fields
-   *
-   * @param {object} latLng - A location (latLng) object from google maps API.
-   * @param {object} map - The settings object that contains all of the necessary metadata for this map.
-   */
-  Drupal.geolocation.codeLatLng = function (latLng, map) {
-    // Update the lat and lng input fields
-    $('.geolocation-hidden-lat.for-' + map.id).attr('value', latLng.lat());
-    $('.geolocation-hidden-lng.for-' + map.id).attr('value', latLng.lng());
-  };
-
-  /**
    * Set/Update a marker on a map
    *
    * @param {object} latLng - A location (latLng) object from google maps API.
diff --git a/src/Plugin/Field/FieldWidget/GeolocationGooglegeocoderWidget.php b/src/Plugin/Field/FieldWidget/GeolocationGooglegeocoderWidget.php
index bb768ec..371d175 100644
--- a/src/Plugin/Field/FieldWidget/GeolocationGooglegeocoderWidget.php
+++ b/src/Plugin/Field/FieldWidget/GeolocationGooglegeocoderWidget.php
@@ -22,6 +22,76 @@ class GeolocationGooglegeocoderWidget extends WidgetBase {
   /**
    * {@inheritdoc}
    */
+  public static function defaultSettings() {
+    return [
+      'populate_address_field' => NULL,
+      'target_address_field' => NULL,
+    ] + parent::defaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+
+    /** @var \Drupal\Core\Entity\EntityFieldManager $field_manager */
+    $field_manager = \Drupal::service('entity_field.manager');
+
+    /** @var \Drupal\Core\Field\FieldDefinitionInterface[] $field_definitions */
+    $field_definitions = $field_manager->getFieldDefinitions($this->fieldDefinition->getTargetEntityTypeId(), $this->fieldDefinition->getTargetBundle());
+
+    $address_fields = [];
+    foreach ($field_definitions as $field_definition) {
+      if ($field_definition->getType() == 'address' && $field_definition->getFieldStorageDefinition()->getCardinality() == 1) {
+        $address_fields[$field_definition->getName()] = $field_definition->getLabel();
+      }
+    }
+
+    if (empty($address_fields)) {
+      return NULL;
+    }
+
+    $element = [];
+
+    $element['populate_address_field'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Store retrieved address data in address field?'),
+      '#default_value' => $this->getSetting('populate_address_field'),
+    ];
+
+    $element['target_address_field'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Select target field to append address data.'),
+      '#description' => $this->t('Only fields of type "address" with a cardinality of 1 are available.'),
+      '#options' => $address_fields,
+      '#default_value' => $this->getSetting('target_address_field'),
+      '#states' => [
+        // Only show this field when the 'toggle_me' checkbox is enabled.
+        'visible' => [
+          ':input[name="fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings][populate_address_field]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = [];
+
+    if (!empty($this->getSetting('populate_address_field'))) {
+      $summary[] = t('Geocoded address will be stored in @field', array('@field' => $this->getSetting('target_address_field')));
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
     // Get this field name and parent.
     $field_name = $this->fieldDefinition->getName();
@@ -56,12 +126,12 @@ class GeolocationGooglegeocoderWidget extends WidgetBase {
     $element['lat'] = [
       '#type' => 'hidden',
       '#default_value' => $lat_default_value,
-      '#attributes' => ['class' => ['geolocation-hidden-lat', "for-{$canvas_id}"]],
+      '#attributes' => ['class' => ['geolocation-hidden-lat']],
     ];
     $element['lng'] = [
       '#type' => 'hidden',
       '#default_value' => $lng_default_value,
-      '#attributes' => ['class' => ['geolocation-hidden-lng', "for-{$canvas_id}"]],
+      '#attributes' => ['class' => ['geolocation-hidden-lng']],
     ];
 
     // Add Google API key to js.
@@ -79,7 +149,8 @@ class GeolocationGooglegeocoderWidget extends WidgetBase {
         'library' => ['geolocation/geolocation.widgets.googlegeocoder'],
         'drupalSettings' => [
           'geolocation' => [
-            'widget_maps' => [
+            'widgetSettings' => [],
+            'widgetMaps' => [
               $canvas_id => [
                 'id' => $canvas_id,
                 'lat' => (float) $lat_default_value,
@@ -92,11 +163,33 @@ class GeolocationGooglegeocoderWidget extends WidgetBase {
         ],
       ],
     ];
+    if ($this->getSetting('populate_address_field')) {
+      $element['map_canvas']['#attached']['drupalSettings']['geolocation']['widgetSettings']['addressFieldTarget'] = $this->getSetting('target_address_field');
+
+      foreach ([
+        'country_code',
+        'administrative_area',
+        'locality',
+        'dependent_locality',
+        'postal_code',
+        'address_line1',
+      ] as $component) {
+        $element[$component] = [
+          '#type' => 'hidden',
+          '#attributes' => [
+            'class' => ['geolocation-hidden-' . $component],
+          ],
+        ];
+      }
+    }
 
     // Wrap the whole form in a container.
     $element += [
       '#type' => 'fieldset',
       '#title' => $element['#title'],
+      '#attributes' => [
+        'class' => ['canvas-' . $canvas_id],
+      ],
     ];
 
     return $element;
