# Address autocomplete in WPForms

> Attach the address widget to the WPForms address field or to plain text fields in WPForms Lite, and fill postcode and city automatically.
>
> https://danadresse.dk/en/guides/wpforms · verified 2026-11-02
WPForms has an **Address** field, which is one of the paid field types. It produces input fields with names like `wpforms[fields][3][address1]`, `wpforms[fields][3][postal]` and `wpforms[fields][3][city]`, where the number is the field id. If you use WPForms Lite, you create three plain text fields and give each one a CSS class. The script below covers both.

## The quick route: the Lynbro Danadresse plugin

The free plugin [Lynbro Danadresse](https://wordpress.org/plugins/lynbro-danadresse/) from wordpress.org adds address autocomplete to WooCommerce, Contact Form 7, Gravity Forms, WPForms, Fluent Forms, Elementor, GiveWP, Forminator and more. It calls the API through your own server, so the key never reaches the browser.

1. In WordPress go to **Plugins → Add New**, search for "Lynbro Danadresse", click **Install** and **Activate**.
2. Create a key under [Keys](/dashboard/keys). Use a normal *live* key **without** allowed domains: the plugin calls the API from your own server, and a domain-locked key is refused there because a server call has no `Origin`.
3. Paste the key under **Lynbro → Danadresse → Settings**. The **Status** tab runs a test lookup with the key.
4. Under **Integrations**, check that WPForms is switched on. The plugin attaches to the **Address** field and fills postcode and city. With WPForms Lite's plain text fields, enter the address field's CSS selector instead (e.g. `.dk-adresse input` from step 2 below).

If you want your own code instead, or postcode and city in separate Lite fields, follow the steps below.

## 1. Create a browser key

Create a *live* key under [Keys](/dashboard/keys) and lock it to the site's domains under **Allowed domains**. See [Browser keys and allowed domains](/en/guides/browser-noegler-domaener).

## 2. Set up the fields

With the **Address** field: choose the **International** scheme, so the field has a postal code instead of a US ZIP code, and hide the region sub-field.

With WPForms Lite: create three **Single Line Text** fields. Under **Advanced → CSS Classes** give them the classes `dk-adresse`, `dk-postnr` and `dk-by`. WPForms puts the class on the field's container, so the selector becomes `.dk-adresse input`.

## 3. The mu-plugin

Save the file as `wp-content/mu-plugins/danadresse.php`:

```php id=mu-plugin run=syntax
<?php
/**
 * Plugin Name: Danadresse autocomplete (WPForms)
 */
if (!defined('ABSPATH')) {
    exit;
}

add_action('wp_enqueue_scripts', function () {
    wp_enqueue_script(
        'danadresse-autocomplete',
        'https://danadresse.dk/static/js/danadresse-autocomplete-1.0.0.js',
        [],
        null,
        true
    );
    wp_add_inline_script('danadresse-autocomplete', <<<'JS'
const API_KEY = "YOUR_BROWSER_KEY";

function setField(el, value, events) {
  if (!el || value == null) return;
  const setter = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(el), "value").set;
  setter.call(el, value);
  for (const type of events || ["input", "change"]) {
    el.dispatchEvent(new Event(type, { bubbles: true }));
  }
}

function streetLine(a) {
  let line = a.vejnavn + " " + a.husnr;
  if (a.etage) line += ", " + a.etage + ".";
  if (a["dør"]) line += " " + a["dør"];
  return line;
}

function attach(input, postnrEl, byEl) {
  DanadresseAutocomplete.attach(input, {
    apiKey: API_KEY,
    onSelect(a) {
      setField(input, streetLine(a), ["change"]);
      setField(postnrEl, a.postnr);
      setField(byEl, a.postnrnavn);
    },
  });
}

function bindAll() {
  // Address field: wpforms[fields][3][address1] → [postal] and [city]
  document.querySelectorAll('.wpforms-form input[name$="[address1]"]').forEach((input) => {
    const form = input.form;
    const named = (part) => form.querySelector('[name="' + input.name.replace("[address1]", "[" + part + "]") + '"]');
    attach(input, named("postal"), named("city"));
  });
  // WPForms Lite: text fields with CSS classes
  document.querySelectorAll(".wpforms-form .dk-adresse input").forEach((input) => {
    const form = input.form;
    attach(input, form.querySelector(".dk-postnr input"), form.querySelector(".dk-by input"));
  });
}
bindAll();
new MutationObserver(bindAll).observe(document.body, { childList: true, subtree: true });
JS
    );
});
```

## 4. Test

Fill in the form, pick a suggestion, and submit it. Check in the notification email (or under **WPForms → Entries**, which needs a paid licence) that postcode and city came through. If you use a scheme other than International, the postcode sub-field may have another name. Check it with **Inspect**. `403 origin_not_allowed` in the console means the domain is missing from the key.

## 5. Optional: check on the server

In the `wpforms_process` action hook you can send street and postcode to `/datavask/adgangsadresser` with a server key without a domain lock and set an error on the field in `wpforms()->process->errors` if the answer is category C. See the [Contact Form 7 guide](/en/guides/contact-form-7) for a full example of the call and [Address cleansing in checkout](/en/guides/datavask-i-checkout) for the categories.

## Next steps

- [Gravity Forms](/en/guides/gravity-forms)
- The plugin on wordpress.org: [Lynbro Danadresse](https://wordpress.org/plugins/lynbro-danadresse/)
