# web app-manifest

## Hva det er

Et web app-manifest, i bestemt form web app-manifestet og i daglig tale bare manifestet, er et
JSON-dokument som beskriver et nettsted som et program: hva det heter, hvilken adresse det åpnes på,
hvilke adresser som hører til det, hvordan vinduet skal se ut, og hvilke bilder som representerer
det. En side peker på filen med et `link`-element der `rel` er `manifest`, og en nettleser som
tilbyr installasjon, leser filen for å avgjøre hva den installerte kopien skal bli. Spesifikasjonen
fra W3C som definerer formatet, kaller det også bare manifestet.

Filen er ren JSON. Den registrerte medietypen er `application/manifest+json` og den registrerte
filendelsen `.webmanifest`, selv om spesifikasjonen godtar enhver JSON-medietype og mange nettsteder
serverer en `manifest.json`. Hvert medlem er valgfritt. Et lite manifest for et oppdiktet nettsted
med tidevannstabeller ser slik ut:

```json
{
    "name": "Harbour Tide Tables",
    "short_name": "Tides",
    "start_url": "/tides/",
    "display": "standalone",
    "background_color": "#ffffff",
    "icons": [
        {
            "src": "/icons/tides-512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ]
}
```

Tre medlemmer avgjør hva appen er, til forskjell fra hvordan den ser ut. `start_url` er siden den
installerte appen åpnes på. `scope` er mengden adresser som regnes som en del av appen; mangler den,
tar spesifikasjonen start-URL-en og skjærer bort filnavn, spørrestreng og fragment, så eksempelet
over eier alt under `/tides/`. `id` er identiteten til appen, og mangler den, faller den tilbake på
start-URL-en. Relative adresser i filen, både for ikoner og for start-URL-en, løses opp mot URL-en
til selve manifestet og ikke mot siden som lenket til det.

Resten er presentasjon. `display` ber om `fullscreen`, `standalone`, `minimal-ui` eller `browser`,
og en nettleser som ikke kan innfri ønsket, går nedover den listen i rekkefølge. Hvert ikon kan ha
et `purpose`: `any` som standard, `maskable` for et bilde som er tegnet for å tåle beskjæring, eller
`monochrome` for et bilde der fargen kastes og bare alfakanalen brukes. `theme_color` farger vinduet
rundt appen. Et tilhørende notat fra W3C legger til `description`, `categories` og `screenshots`,
som installasjonsdialoger og appbutikker kan vise.

## Hvorfor det er viktig

Manifestet er den eneste delen av en installasjon nettstedet selv styrer. Spesifikasjonen overlater
beslutningen om å installere til nettleseren: den kan tilby en måte å installere på, og hver
nettleser setter sine egne betingelser, der noen krever bestemte medlemmer. Et team leverer
inndataene, og nettleseren avgjør hva den gjør med dem. Det nyttige spørsmålet er derfor mindre om
nettstedet skal ha et manifest, og mer hva manifestet lover.

Identiteten er løftet som lever lenger enn filen. Når en nettleser henter manifestet på nytt, krever
spesifikasjonen at den bruker `id` for å avgjøre om den nye filen gjelder en app som allerede er
installert. Fordi en manglende `id` er det samme som start-URL-en, endrer en flytting av startsiden
identiteten i det stille, og den nye filen beskriver da en annen app enn den som ligger på leserens
enhet. Å låse `id` i den første utgivelsen koster én linje og fjerner den risikoen.

Omfanget avgjør hvor appvinduet slutter. Navigasjon innenfor `scope` blir i det installerte vinduet.
En lenke som går ut av det, åpnes fortsatt, men spesifikasjonen forventer at nettleseren viser
leseren at vedkommende er utenfor appen, så et omfang som er smalere enn nettstedet, får vanlige
lenker mellom seksjonene til å se ut som utganger.

Ikonene er der det meste av den synlige skaden skjer. Startmenyer og hjemskjermer beskjærer ikoner
til sirkler, avrundede kvadrater og andre former, og en logo som fyller hele kvadratet sitt, mister
kantene. Spesifikasjonen definerer den trygge sonen for et maskerbart ikon som en sirkel i midten
med en radius på to femtedeler av ikonstørrelsen, og alt utenfor den kan bli skåret bort. Et
monokromt ikon beholder bare alfakanalen, så et ikon tegnet på en ugjennomsiktig bakgrunn blir til
et ensfarget kvadrat.

Fargemedlemmene er smalere enn de ser ut. `background_color` er bare ment for øyeblikket før
stilarket kommer, og spesifikasjonen forbyr nettleseren å bruke den når stilarket er tilgjengelig.
Det er fargen på den første rammen, og ingenting etter den.

## Slik ser det ut i praksis

Dette nettstedet bygger manifestet fra en mal i stedet for å vedlikeholde en fil for hånd.
Hugo-konfigurasjonen registrerer `application/manifest+json` med endelsen `webmanifest` og gjør
manifestet til et utdataformat for hjemmesiden på hvert språk, så hvert språk får sin egen fil, og
hodet på hver side lenker til filen for sitt eget språk. Konfigurasjonen skriver ned hvorfor: én
felles kopi kan bare angi én start-URL, og en dansk besøkende som installerte nettstedet, fikk en
app som åpnet den engelske hjemmesiden.

Malen setter sammen manifestet som et kart og gir det til JSON-koderen i Hugo, så escaping og
kommaer er koderens problem, og et manglende komma kan ikke sendes ut. Hver ikonadresse starter ved
roten av verten. Kommentaren i malen forklarer grunnen: en relativ adresse i
`/da/manifest.webmanifest` ville blitt løst opp under `/da/`, og hvert ikon på dansk ville gitt 404.
Selve ikonene leses fra disk i tre mapper, én per formål, med ti størrelser hver fra 36 til 512
piksler, og størrelsen hentes fra filnavnet, så en størrelse som generatoren legger til, dukker opp
i manifestet uten at noe må redigeres.

`id` er låst til hjemmeadressen for språket, og `scope` er hele opprinnelsen, så en lenke til et
annet språk blir i det installerte vinduet. Skjermbildene heter `<lang>-<form_factor>-<WxH>.webp`,
og malen leser alle tre opplysningene fra filnavnet: engelsk og dansk har hver ett bredt bilde på
1280 ganger 800 og ett smalt på 780 ganger 1688. Et språk uten skjermbilder får ikke noe
`screenshots`-medlem i det hele tatt, heller enn en tom liste.

[Kolofonsiden](/nb/credits/) lister spesifikasjonen fra W3C blant standardene nettstedet følger, og
PWABuilder blant de eksterne sjekkene hvem som helst kan kjøre: en tjeneste som leser manifestet og
resten av det som gjør nettstedet installerbart, fra Microsofts maskiner.

[Installasjonssiden](/nb/install/) er leserens halvdel av den samme filen. Den viser hvor hver
nettleser gjemmer installasjonskommandoen, nevner at Apples nettlesere aldri tilbyr den av seg selv,
og at Firefox på datamaskin ikke installerer nettapper i det hele tatt, og den forteller hva leseren
kan forvente: den installerte appen er et ikon og et eget vindu, og den trenger en tilkobling, fordi
frakoblet bruk krever en service worker.

## Hvor det går galt

**Hvert ikon gir 404 på en oversatt sti.** En relativ `src` løses opp mot URL-en til manifestet, så
et manifest som serveres under et språkprefiks, ber om ikoner under det prefikset. Skriv
ikonadresser fra roten av verten, eller som fullstendige URL-er.

**Den installerte appen åpnes på feil språk.** Ett manifest kan angi én start-URL, så hver leser
installerer den samme hjemmesiden. Lever ett manifest per språk, hvert med sin egen `start_url` og
`id`, og lenk til det som passer, fra hver side.

**Installerte kopier overser det nye manifestet.** Uten `id` er identiteten start-URL-en, så å
flytte startsiden gir filen en ny identitet, og nettleseren bruker den ikke lenger på appen leserne
allerede har. Sett `id` før den første utgivelsen, og la den være i fred etterpå.

**Startmenyen beskjærer logoen.** Et ikon med formålet `any` plasseres eller skjæres til slik
plattformen finner det best. Legg til et `maskable`-ikon med alt som betyr noe, innenfor sirkelen i
midten, der radien er 40 % av ikonet.

**Endringer i manifestet endrer ingenting.** HTML-standarden bruker bare det første `link`-elementet
der `rel` inneholder `manifest`, så når et tema eller et tillegg har lagt inn sin egen lenke
tidligere på siden, er filen som redigeres, aldri den som leses. Hold deg til nøyaktig én
manifestlenke per side.

## Les mer

- [Web Application Manifest](https://www.w3.org/TR/appmanifest/) — hvert medlem, hvordan en
  nettleser behandler filen, og reglene for `id`, `scope` og formålet med ikoner.
- [Web App Manifest - Application Information](https://www.w3.org/TR/manifest-app-info/) —
  `description`, `categories` og `screenshots`, med formfaktorer og etiketter.
- [IANA: application/manifest+json](https://www.iana.org/assignments/media-types/application/manifest+json)
  — registreringen av medietypen og filendelsen `.webmanifest`.
- [HTML Standard: link type manifest](https://html.spec.whatwg.org/multipage/links.html#link-type-manifest)
  — hvordan manifestlenken hentes, og hvorfor bare den første teller.

<https://engineer.company/nb/glossary/webmanifest/>
