Spring til indhold

Adressefelt til checkout og formularer

Ét script-tag gør et almindeligt inputfelt til et adressefelt med forslag fra det officielle adresseregister: kunden skriver, vælger adressen og eventuelt etage og dør, og postnummer, by og BFE-nummer lander i formularens egne felter. Feltet kalder Grundfast direkte fra browseren med en offentlig nøgle, så du skal ikke bygge en proxy på din server.

Vælg en adresse — har bygningen flere lejligheder, spørger feltet bagefter om etage og dør. Det, der kommer ud, vises her.

Feltet ovenfor er den samme fil, som din side indlæser. På denne side kører den uden nøgle mod vores demo-endpoints; på din side bruger den din offentlige nøgle. Forslagene er de samme.

Kom i gang

  1. Opret en offentlig nøgle

    Under Nøgler i dashboardet vælger du Offentlig og skriver de domæner, feltet skal virke på, fx butik.dk og www.butik.dk. Tilføj localhost:3000 (eller den port, du udvikler på), hvis du vil prøve lokalt. Brug en testnøgle (gf_pub_test_), mens du bygger.

  2. Indsæt scriptet

    Læg tagget før </body> eller i <head> med defer. data-felt er en CSS-selektor for det felt, kunden skriver adressen i; data-postnr og data-by peger på felterne, der skal udfyldes.

    html
    <script
      src="https://grundfast.dk/widget/v1/grundfast-adresse.js"
      defer
      data-key="gf_pub_live_..."
      data-felt="#adresse"
      data-postnr="#postnr"
      data-by="#by"
    ></script>
  3. Prøv det

    Skriv en adresse. Vises der ingen forslag, står årsagen i browserens konsol — se Fejlfinding.

Kan du ikke sætte en selektor på scriptet, kan du i stedet markere selve feltet. Her skal indstillingerne have data-gf- foran, så de ikke kan forveksles med temaets egne attributter:

html
<input id="adresse" name="adresse" data-grundfast-adresse
       data-gf-postnr="#postnr" data-gf-by="#by">

Felter, der først dukker op senere — en checkout, der tegnes af JavaScript, eller et trin i en formular — får feltet på, når de vises. Guides til de enkelte platforme: WooCommerce, Shopify og alle guides om adresser.

Offentlige nøgler

En almindelig nøgle (gf_live_, gf_test_) er hemmelig og hører til på en server. En offentlig nøgle (gf_pub_live_, gf_pub_test_) er lavet til at stå i en webside, hvor alle kan læse den. Derfor kan den langt mindre:

  • Kun fra dine domæner. Kaldet skal komme fra en side på et af nøglens tilladte domæner. API’et læser browserens Origin-header (eller Referer, hvis Origin mangler). Et kald uden nogen af dem afvises.
  • Kun adresseopslag. Nøglen åbner adressesøgning og autocomplete, opslag af én adresse, datavask af én adresse og postnumre — alle som GET. Registre, batch, eksport og din konto kræver en hemmelig nøgle.
  • En grænse pr. besøgende. Ud over planens burst-grænse får hver IP-adresse højst 120 kald i minuttet med samme nøgle, så én, der kopierer nøglen, ikke kan bruge hele din kvote på et øjeblik.
Du skriverGælder for
butik.dkhttps://butik.dk og http://butik.dk — ikke www.butik.dk
www.butik.dkKun www.butik.dk
*.butik.dkAlle underdomæner, fx www.butik.dk og test.shop.butik.dk — ikke butik.dk selv
https://butik.dkKun over https
localhost:3000Din lokale udviklingsserver på port 3000

Et domæne uden port gælder kun standardporten. * alene og *.dk afvises. Et domæne med æ, ø eller å skrives i den form, browseren sender: xn---formen (punycode). Ændrer du listen, slår det igennem inden for et halvt minut.

Hvad koster det?

Kald med en offentlig nøgle tæller som alle andre kald, og hvert opslag er ét kald. Feltet spørger først fra to tegn og venter på en kort pause i tastningen, så en kunde, der skriver en adresse, typisk udløser en håndfuld kald — plus ét, når bygningen har lejligheder. En afvist forespørgsel (forkert domæne, forkert endpoint eller over grænsen) tæller ikke.

Origin-tjekket stopper andre websites i at bruge din nøgle fra deres besøgendes browsere. Et script uden for en browser kan skrive en hvilken som helst Origin; det er grænsen pr. IP-adresse og de få endpoints, der begrænser skaden. Mistænker du misbrug, så tilbagekald nøglen og opret en ny — det tager et minut at skifte den i scriptet.

Nøglen sendes som ?token= i et almindeligt GET, så browseren ikke skal lave et CORS-preflight først. Vil du kalde endpoints selv med en offentlig nøgle, virker Authorization: Bearer også; svaret åbnes for dit domæne med Access-Control-Allow-Origin.

Selv kalde søgningen fra browseren
const res = await fetch(
  'https://api.grundfast.dk/v1/adresse/search?per_side=8&q=' +
    encodeURIComponent('Jægersborggade 10') +
    '&token=gf_pub_live_...'
);
const { results } = await res.json();

Indstillinger

Alle indstillinger er data--attributter på script-tagget. På et markeret felt skrives de med data-gf- foran og gælder kun det felt. Felt-indstillingerne er CSS-selektorer; de slås først op i feltets egen formular.

AttributBetydning
data-keyDen offentlige nøgle, gf_pub_live_… eller gf_pub_test_….
data-feltSelektor for det eller de felter, der skal have forslag, fx #billing_address_1.
data-postnr, data-byFelterne til postnummer og by. Er en af dem sat, får adressefeltet kun vej, husnummer, etage og dør; ellers hele adressen.
data-adresselinjeEt felt til “Vej 10, 2. th” — hvis det ikke er det felt, kunden skriver i.
data-vejnavn, data-husnrVejnavn og husnummer hver for sig.
data-etage, data-doerEtage og dør hver for sig (tomme, når der ikke er nogen).
data-kommunekodeFirecifret kommunekode, fx 0101.
data-adgangsadresse-id, data-adresse-idDAR-id’er for husnummeret og for den konkrete bolig. Godt at gemme på ordren.
data-bfeBFE-nummeret for ejendommen, når det er kendt.
data-enheder="false"Spring trinnet med etage og dør over.
data-css="false"Indsæt ikke widgettens eget stylesheet.
data-min-length, data-delayAntal tegn før første opslag (standard 2) og pausen i millisekunder (standard 180).
data-observe="false"Lad være med at holde øje med felter, der dukker op senere.

Hændelsen, når en adresse er valgt

Når kunden har valgt, sender feltet hændelsen grundfast:adresse. Den bobler op gennem siden, så du kan lytte på document eller formularen. detail er hele adressen:

javascript
document.addEventListener('grundfast:adresse', (e) => {
  const a = e.detail;
  console.log(a.betegnelse, a.bfe_nummer);
});
event.detail
{
  "betegnelse": "Jægersborggade 10, st. tv, 2200 København N",
  "adresselinje": "Jægersborggade 10, st. tv",
  "vejnavn": "Jægersborggade",
  "husnr": "10",
  "etage": "st",
  "doer": "tv",
  "postnr": "2200",
  "postnrnavn": "København N",
  "kommunekode": "0101",
  "adgangsadresse_id": "0a3f507a-a100-32b8-e044-0003ba298018",
  "adresse_id": "0a3f509f-1325-32b8-e044-0003ba298018",
  "bfe_nummer": 9866621,
  "koordinat": { "lon": 12.5449906, "lat": 55.6921031 }
}
  1. Vej, husnummer, etage og dør i den form, en pakkelabel skal have.

  2. adgangsadresse_id er opgangen eller huset; adresse_id er den konkrete bolig og er null, når der ikke er valgt etage og dør.

  3. Nøglen til resten af Grundfast: brug den på din server med en hemmelig nøgle, fx til BBR.

Fra JavaScript

I en app, der selv tegner sine felter, kobler du feltet på med GrundfastAdresse.attach og fjerner det igen med destroy(). Indstillingerne er de samme som attributterne, skrevet i camelCase, og felterne kan være elementer i stedet for selektorer.

javascript
const felt = GrundfastAdresse.attach(document.querySelector('#adresse'), {
  key: 'gf_pub_live_...',
  postnr: '#postnr',
  by: '#by',
  onSelect: (adresse) => gemPaaOrdren(adresse),
});

// Når formularen forsvinder:
felt.destroy();

Værdierne skrives, som hvis kunden selv havde tastet dem: feltets egen setter og bagefter input- og change-hændelser. Derfor opdaterer React-, Vue- og blok-checkouts deres tilstand uden ekstra kode.

Udseende

Forslagslisten arver skrifttypen fra siden. Farver og hjørner styres med CSS-variabler, som du sætter på :root:

css
:root {
  --gf-adr-bg: #fff;          /* listens baggrund */
  --gf-adr-fg: #1a1a1a;       /* tekst */
  --gf-adr-border: #c8c8c8;
  --gf-adr-active: #eef3ff;   /* forslaget, der er markeret */
  --gf-adr-active-fg: inherit;
  --gf-adr-radius: 6px;
}

Vil du style alt selv, så sæt data-css="false" og brug klasserne .gf-adr-liste (listen), .gf-adr-valg (et forslag; det markerede har aria-selected="true") og .gf-adr-note (overskriften i trinnet med etage og dør).

Feltet er en tilgængelig combobox: piletasterne flytter i listen, Enter vælger, Escape lukker, og en skærmlæser får antallet af forslag læst op. Enter sender stadig formularen, når intet forslag er markeret.

Versioner og cache

URLIndholdCache
/widget/v1/grundfast-adresse.jsSeneste 1.x. Får rettelser og nye indstillinger, men aldrig ændringer, der bryder en eksisterende opsætning.1 time
/widget/1.0.0/grundfast-adresse.jsPræcis version 1.0.0. Filen ændres aldrig.1 år, immutable

Vil du låse filen med Subresource Integrity, så brug den faste version:

html
<script
  src="https://grundfast.dk/widget/1.0.0/grundfast-adresse.js"
  integrity="sha384-zgjWtsuGrsYs+BZIp0mG5VEIvkOffWtOKqoxEBZG2u3Zbu4cnV9DVPhiFd+o/+ia"
  crossorigin="anonymous"
  defer
  data-key="gf_pub_live_..."
  data-felt="#adresse"
></script>

Fejlfinding

Feltet blokerer aldrig formularen: fejler et opslag, lukker listen, og kunden kan skrive adressen selv. Årsagen skrives én gang i browserens konsol med [grundfast-adresse] foran.

I konsollenÅrsagGør dette
origin https://… is not allowed for this public keySiden ligger på et domæne, der ikke står på nøglen.Tilføj domænet under Nøgler. Husk både butik.dk og www.butik.dk, eller brug *.butik.dk.
public key requires an Origin or Referer headerSiden sender hverken Origin eller Referer, fx på grund af en streng Referrer-Policy i en iframe.Tillad mindst origin i sidens Referrer-Policy.
public keys only open the address autocomplete endpointsNøglen bruges til et andet endpoint end adresseopslag.Kald det endpoint fra din server med en hemmelig nøgle.
no public keyScriptet mangler data-key.Sæt data-key="gf_pub_live_…" på script-tagget.
rate limit exceededMere end 120 kald i minuttet fra samme IP med samme nøgle, eller planens burst-grænse.Vent; listen virker igen efter Retry-After sekunder.

Har din side en Content-Security-Policy, skal script-src tillade https://grundfast.dk og connect-src tillade https://api.grundfast.dk. Widgetten indsætter et lille stylesheet; tillader din style-src ikke det, så sæt data-css="false" og style klasserne selv. Fejlkoderne står samlet under Fejl og statuskoder.