JavaScript Autocomplete
Danish address autocomplete for any text input. Attach it to a field you already have, pick a suggestion, and your
select handler gets the address — no framework and no build step.
Under the hood it is DAWA's own widget, dawa-autocomplete2 1.1.0, unchanged. This package points it at getaddress.dk with your domain token, adds a default stylesheet, and passes every other option straight through. The current version is 1.2.0.
Suggestions are free; each address picked is one look-up. The widget asks for text-only suggestions
(kun_tekst=true), which are never metered, and when an address is picked it fetches that one record by
id and hands it to your select — the same object as always. See What it costs.
Two widgets, both supported
-
Our widget,
getaddress-dk-autocomplete:getAddressDk.autocomplete(input, '{your-domain-token}', { select(valgt) { … } }). Pick it for getaddress.dk's defaults: the token is an argument, the API address is built in, and a stylesheet is included. Everything on this page from Install on is about it. -
DAWA's open-source widget,
dawa-autocomplete2, pointed at us withbaseUrl: 'https://api.getaddress.dk/t/{your-domain-token}'. Pick it if you would rather use the Danish state's own widget as published: it is widely known, and its full option set is documented upstream (GitHub, npm). See Using dawa-autocomplete2.
Both take a domain token, never an API key, and both call select with the same object —
valgt.tekst and valgt.data in DAWA's field names — so one handler works for either.
They differ in what they cost: ours asks for free text-only suggestions and pays one look-up for the address picked;
dawa-autocomplete2 as published asks for DAWA's full answers, each of which is a look-up once it suggests addresses
(unless you add kun_tekst).
Install
From npm:
npm install getaddress-dk-autocomplete
import { autocomplete } from 'getaddress-dk-autocomplete';
autocomplete(document.getElementById('adresse'), '{your-domain-token}', {
select(valgt) {
console.log(valgt.tekst, valgt.data.id);
}
});
Or with a <script> tag, which puts getAddressDk on window:
<link rel="stylesheet" href="https://cdn.getaddress.io/scripts/getaddress-dk-autocomplete-1.2.0.css">
<script src="https://cdn.getaddress.io/scripts/getaddress-dk-autocomplete-1.2.0.js"></script>
The stylesheet link is optional: the script injects the same stylesheet once by itself. Link it if you set
injectStyles: false, or would rather the styles load with the page. The npm package ships ESM, CommonJS
and TypeScript types; its builds import dawa-autocomplete2 (pinned to 1.1.0) as a dependency, while the
<script> build has it inside.
A domain token, never an API key
Anything in browser JavaScript is readable by anyone who opens the page. Give the widget a
domain token (dtoken_…), made in the console for your
site's domain: it only works from there, so publishing it costs you nothing. Never put your API key in a web page
— the API refuses an API key sent from a browser, and autocomplete() throws if it is given anything
but a domain token.
The token goes in the URL path (https://api.getaddress.dk/t/{your-domain-token}/autocomplete?…), because
dawa-autocomplete2 builds its own query strings and only takes a base URL.
A full example
<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="utf-8">
<title>Adresse</title>
<link rel="stylesheet" href="https://cdn.getaddress.io/scripts/getaddress-dk-autocomplete-1.2.0.css">
</head>
<body>
<label for="adresse">Adresse</label>
<input id="adresse" type="search">
<label for="vej">Vej og husnummer</label>
<input id="vej" type="text">
<label for="postnr">Postnummer</label>
<input id="postnr" type="text">
<label for="by">By</label>
<input id="by" type="text">
<script src="https://cdn.getaddress.io/scripts/getaddress-dk-autocomplete-1.2.0.js"></script>
<script>
getAddressDk.autocomplete('adresse', '{your-domain-token}', {
select: function (valgt) {
var a = valgt.data;
document.getElementById('vej').value = a.vejnavn + ' ' + a.husnr;
document.getElementById('postnr').value = a.postnr;
document.getElementById('by').value = a.postnrnavn;
}
});
</script>
</body>
</html>
valgt.tekst is the address on one line and valgt.data is the address record in DAWA's field
names (id, vejnavn, husnr, etage, dør,
postnr, postnrnavn, x, y and the rest). The widget fetches that
record when the address is picked, so select runs a moment after the pick. The first argument is the
input itself, its id, or a CSS selector.
What it costs
Suggestions are free (rate limited) — street names, access addresses and addresses alike: the
widget asks for them with kun_tekst=true, so each suggestion carries its text and its record's
id and href, nothing more. Each address picked is one look-up: the widget
fetches it from /adresser/{id}?struktur=mini (or /adgangsadresser/{id} with
adgangsadresserOnly) and hands select the suggestion with that record in data,
key for key what DAWA's autocomplete carried. If it cannot be fetched — your plan's limit is reached, say —
select is not called and selectError is.
kunTekst: false brings back version 1.0's behaviour: DAWA's full answers, no request on a pick, and one
look-up for every answer that suggests addresses. See Autocomplete.
Options
Every dawa-autocomplete2 option
works as before; apiUrl, injectStyles, kunTekst, struktur,
selectError and googlePlacesFallback are ours.
| Option | Default | What it does |
|---|---|---|
| select | – | Called with the picked suggestion once its record is fetched: { data, stormodtagerpostnr, type, tekst, forslagstekst, caretpos }. |
| type | 'adresse' | 'adresse' or 'adgangsadresse': what a completed suggestion resolves to. |
| adgangsadresserOnly | false | Stop at the access address (no floor or door). Same as type: 'adgangsadresse'. |
| params | {} | Extra query parameters on every request, e.g. { kommunekode: '101' } or { postnr: '2400' }. |
| fuzzy | true | Fuzzy matching. |
| stormodtagerpostnumre | true | Show large-recipient postcodes in suggestions. |
| supplerendebynavn | true | Show supplementary town names in suggestions. |
| minLength | 2 | Characters before the first request. |
| multiline | false | Show each suggestion on several lines. |
| debounce | – | Milliseconds to wait for typing to pause before asking. Unset asks on every keystroke. |
| id | – | Start the input filled with the address with this id (one look-up). |
| render | – | Replace the list rendering entirely (advanced; see dawa-autocomplete2). |
| apiUrl | https://api.getaddress.dk | Ours. The API origin, e.g. for staging. The token is added to it. |
| injectStyles | true | Ours. Inject the default stylesheet once. |
| kunTekst | true | Ours. Free text-only suggestions, the address picked fetched by id (one look-up). false: DAWA's full answers, each one that suggests addresses a look-up. |
| struktur | 'mini' | Ours. The record select gets in data: 'mini' (what DAWA's autocomplete carried), 'flad' or 'nestet'. Still one look-up. |
| selectError | logs it | Ours. (error, suggestion) => …, called instead of select when the address picked could not be fetched; error.status is the HTTP status (429 when your plan's limit is reached). |
| googlePlacesFallback | true | Ours. Use the Google Places fallback when it is switched on for the subscription. false keeps the page on DAR only. |
| baseUrl | built from apiUrl and the token | Set it only to bypass the token path entirely, e.g. through your own proxy. |
autocomplete() returns dawa-autocomplete2's handle: destroy() removes the list and every
listener, selected() returns the picked suggestion with its record once fetched (or null),
and id(uuid) fills the input with that address. In React, Vue or Svelte, call destroy() when your component unmounts.
Coming from DAWA
Swap the script and keep your select handler. Where you had:
<script src="https://cdn.dataforsyningen.dk/dawa/assets/dawa-autocomplete2/1.0.2/dawa-autocomplete2.min.js"></script>
<script>
dawaAutocomplete.dawaAutocomplete(document.getElementById('adresse'), {
select: function (valgt) { console.log(valgt.tekst); }
});
</script>
write:
<script src="https://cdn.getaddress.io/scripts/getaddress-dk-autocomplete-1.2.0.js"></script>
<script>
getAddressDk.autocomplete(document.getElementById('adresse'), '{your-domain-token}', {
select: function (valgt) { console.log(valgt.tekst); }
});
</script>
The suggestions, the select argument and every option (fuzzy, params,
adgangsadresserOnly, multiline, id …) are the same, because the widget is the
same; only the cost differs — the suggestions are free and each address picked is one look-up. Your existing CSS for .dawa-autocomplete-suggestions keeps working; set
injectStyles: false if you would rather ours stayed out of the way.
Using dawa-autocomplete2
DAWA's own dawa-autocomplete2
works with getaddress.dk as published, without this package: give it our API as its baseUrl, with your
domain token in the path. Its options, markup and styling are documented in its
README; if you already
use it, nothing else changes — not your markup, not your CSS, not your select handler. See
A domain token in the path.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dawa-autocomplete2@1.1.0/dist/css/dawa-autocomplete2.css">
<script src="https://cdn.jsdelivr.net/npm/dawa-autocomplete2@1.1.0/dist/js/unfilled/dawa-autocomplete2.min.js"></script>
<div class="dawa-autocomplete-container">
<input id="adresse" type="search">
</div>
<script>
dawaAutocomplete.dawaAutocomplete(document.getElementById('adresse'), {
baseUrl: 'https://api.getaddress.dk/t/{your-domain-token}',
select: function (valgt) { console.log(valgt.tekst); }
});
</script>
Or from npm:
npm install dawa-autocomplete2, then import { dawaAutocomplete } from 'dawa-autocomplete2'.
As published, dawa-autocomplete2 asks for DAWA's full answers, so each answer that suggests addresses is one look-up.
For free suggestions with it too, add params: { kun_tekst: true } and fetch the address picked yourself
— one look-up — which is what our widget does for you:
dawaAutocomplete.dawaAutocomplete(document.getElementById('adresse'), {
baseUrl: 'https://api.getaddress.dk/t/{your-domain-token}',
params: { kun_tekst: true },
select: async function (valgt) {
// valgt.data is { id, href } only; a street name never reaches select.
var svar = await fetch('https://api.getaddress.dk/t/{your-domain-token}/adresser/' + valgt.data.id + '?struktur=mini');
var adresse = await svar.json();
console.log(adresse.vejnavn, adresse.husnr, adresse.postnr, adresse.postnrnavn);
}
});
This package exports that function too, unchanged, as getAddressDk.dawaAutocomplete (or
import { dawaAutocomplete } from 'getaddress-dk-autocomplete'). The full migration guide, in Danish:
Skift fra DAWA.
Styling
dawa-autocomplete2 renders its list (ul.dawa-autocomplete-suggestions, items
li.dawa-autocomplete-suggestion, the highlighted one also .dawa-selected) into an element
straight after the input, and styles nothing itself. This package classes that element
.getaddress-dk-autocomplete and floats the list under the input — no wrapper <div>
needed. With the Google Places fallback, Google's suggestions use the same
markup, followed by .getaddress-dk-autocomplete__attribution (Google Maps), which must stay visible. Every rule has zero specificity, so any CSS of yours wins. Reskin it with the custom properties:
.getaddress-dk-autocomplete {
--gadk-bg: #fff;
--gadk-border: #d7d9e3;
--gadk-text: #1f2033;
--gadk-hover-bg: #f2f3f7;
--gadk-hover-text: inherit;
--gadk-radius: 6px;
}
Dark mode follows prefers-color-scheme unless you set data-gadk-theme="light" on any
ancestor, e.g. <html>.