# Feed

## Hvad det er

Et feed er en fil på en fast adresse, der lister et sites nyeste indlæg i en
form, software kan læse: hvert indlæg med titel, dato, et id der aldrig skifter,
og som regel selve teksten. Et program henter filen med faste mellemrum og viser
kun det, der er kommet til siden sidst. Det kaldes også webfeed eller
syndikeringsfeed, og mange siger »RSS-feed« om dem alle, uanset hvilket format
der ligger nedenunder.

Det, der skiller det ud, er retningen. Et nyhedsbrev bliver skubbet ud:
afsenderen har en liste over adresser og sender til hver enkelt. Et feed bliver
hentet: udgiveren lægger én fil på serveren, og hver abonnents feedlæser henter
den, sammenligner den med den kopi, den så sidst, og beholder de indlæg, den
ikke kender i forvejen. Udgiveren får aldrig at vide, hvem der abonnerer,
abonnenten afleverer aldrig en mailadresse, og at stoppe kræver kun, at man
sletter én linje i sin læser.

Tre formater bærer næsten alle feeds på nettet. RSS 2.0 er XML, daterer sine
indlæg i stilen fra RFC 822 (`Sat, 07 Sep 2002 00:00:01 GMT`) og erklæres
frosset af sin egen specifikation. Atom, som IETF udgav som RFC 4287 i december
2005, er også XML og strengere: hvert feed og hvert indlæg har et permanent `id`
og et `updated`-tidsstempel i formen fra RFC 3339, og en forfatter skal være
angivet et sted. JSON Feed, i version 1.1 siden august 2020, siger det samme i
JSON til udviklere, der helst er fri for at parse XML.

En side fortæller software, hvor dens feeds ligger, med
`<link rel="alternate">`-elementer i sit head, hvert med sin medietype:
`application/rss+xml`, `application/atom+xml` eller `application/feed+json`.
Sådan finder en læser feedet ud fra intet andet end sitets almindelige adresse.

## Hvorfor det betyder noget

Den første beslutning er, om der overhovedet skal være et. Et feed er et output
mere, der skal have en skabelon, valideres og holdes stabilt i årevis, for et
publikum, der er mindre end et socialt netværks. Til gengæld er det den eneste
abonnementskanal, der hverken kræver platform, konto eller mailingliste, og der
sidder ingen rangeringsalgoritme mellem et indlæg og de mennesker, der bad om at
se det.

Den anden beslutning er formaterne. Nogle læsere tager kun RSS og andre kun
Atom, og man kan ikke på forhånd vide, hvilket en given abonnents læser vil
have. At udgive begge dækker hullet for prisen af en skabelon mere, og JSON Feed
lægger et tredje oveni til software skrevet af folk, der hellere vil arbejde med
JSON. Hvert ekstra format er en fil mere, der skal holdes i takt: samme indlæg,
samme id'er, samme datoer.

Den tredje er, hvor meget tekst hvert indlæg skal have. Et feed med den fulde
tekst lader folk læse hele stykket i deres læser, hvilket er meget af pointen
med en læser, og det koster udgiveren sidevisninger. Et feed med kun resuméer
sender læseren hen på sitet for hvert eneste indlæg. Begge dele er legitime;
valget står mellem, hvor langt teksten rejser, og hvor tit selve siden bliver
besøgt.

Uanset svarene er adressen et løfte. Læsere henter den URL, de fik, efter en
plan, hver læser selv vælger (RSS lader et feed foreslå et interval i minutter
med `ttl`, og læseren må gerne se bort fra det), og mange bliver ved i årevis.
Når en feedadresse først er sendt ud, bliver den der.

## Sådan ser det ud i praksis

Dette site udgiver alle tre formater fra sin danske forside, på `/da/index.xml`
(RSS), `/da/atom.xml` (Atom) og `/da/feed.json` (JSON Feed).
[Kolofonen lister dem og de tjenester, der tjekker dem](/da/credits/): alle tre
har den fulde tekst, og der er to XML-feeds og ikke ét, fordi nogle læsere kun
tager det ene af de to, og det er ikke til at forudsige hvilket. W3C's
feed-validator tjekker Atom- og RSS-feedet, og JSON Feed-validatoren tjekker det
tredje, som W3C's tjeneste ikke dækker, fordi den er ældre end formatet. W3C's
tjeneste advarer om, at de fleste indlæg deler ændringsdato. Siden lader
advarslen stå i stedet for at skjule den: datoerne kommer fra git-historikken,
og de fleste af siderne blev skrevet i de samme få commits.

[Kontaktsiden tilbyder feedsene som en måde at følge virksomheden på uden en konto](/da/contact/),
ved siden af de sociale profiler, og gentager, at alle tre har den fulde tekst
af alt, der udgives.

Ingen af de tre er skrevet i hånden eller laves, når nogen spørger efter dem. I
[projektet, der byggede sitet](/da/portfolio/built-a-multilingual-static-site-in-hugo-126/),
genereres sitet udelukkende ved bygningstid uden en backend, der kører, hver
side udgives i fire repræsentationer fra ét indholdstræ, og forsiden lægger tre
syndikeringsfeeds og et manifest for en installerbar applikation oveni.

## Hvor det går galt

**Alle gamle indlæg dukker op igen som nye.** Efter et redesign, et domæneskifte
eller en ny skabelon ser abonnenterne snesevis af indlæg, de læste for måneder
siden. Læsere genkender et indlæg på dets id, Atoms `id`, RSS' `guid` eller JSON
Feeds `id`, og når den streng skifter, er indlægget nyt for dem. RFC 4287 siger
udtrykkeligt, at et indlægs `id` skal overleve flytning, migrering og
genudgivelse. Et permalink er kun et godt id, så længe sitet lover at beholde
den gamle streng efter en flytning. I RSS bør man også sige, hvad `guid` er:
specifikationen sætter `isPermaLink` til true som standard, og dette sites
RSS-skabelon skriver alligevel `isPermaLink="true"`, fordi en læser, der gætter
den anden vej, importerer hvert indlæg igen som en dublet.

**Feedet påstår at være ændret ved hvert build.** Datoen på feedniveau flytter
sig, hver gang sitet bygges, uanset om der er udgivet noget, så software, der
holder øje med den dato, slår alarm over ingenting. Årsagen er en skabelon, der
stempler klokkeslættet ved bygningstid. RSS definerer `lastBuildDate` som sidste
gang, kanalens indhold ændrede sig, og Atoms `updated` på feedniveau betyder
stort set det samme, så datoen bør komme fra det nyeste indlæg. Dette sites
Atom-skabelon tager den fra det nyeste indlæg af netop den grund.

**Feedet holder op med at lade sig parse efter en typografisk ændring.** Læsere
melder feedet i stykker, og en validator peger på en udefineret entitet i den
første artikel med et typografisk anførselstegn. XML har fem foruddefinerede
navngivne entiteter, `lt`, `gt`, `amp`, `apos` og `quot`, mens HTML definerer
hundredvis flere. En Markdown-renderer, der skriver anførselstegn og
tankestreger som HTML's navngivne entiteter, laver markup, der er fin på en side
og fatal inde i et XML-element. Escape HTML'en, før den sættes ind, sådan som
Atoms indhold med `type="html"` forventer, eller pak den ind i en CDATA-sektion,
som RSS Best Practices Profile tillader til `content:encoded`. Dette sites
Atom-skabelon escaper sit indhold, og kommentaren ved siden af noterer, at
feedet slet ikke lod sig parse, da det blev skrevet råt.

**Abonnenterne glider væk efter en flytning, og udgiveren hører intet.** Et feed
har ingen afmeldingsknap og ingen liste, der skrumper, så det eneste tegn er
stilhed. Feedets adresse er ændret, eller filen er fjernet, og hver læser, der
henter den gamle URL, får nu en fejl. Hold den gamle adresse i live, enten med
selve feedet eller med en permanent omdirigering. Dette site beholder sine
RSS-feeds på `index.xml`, standardnavnet i den generator, det er bygget med,
fordi det er den adresse, eksisterende læsere henter; og på et sprog, sitet ikke
annoncerer, skriver det stadig velformede feeds med nul indlæg, så en læser får
et gyldigt dokument frem for en 404.

**To feeds smelter sammen til ét i en abonnementsdialog.** En browserudvidelse
eller en læser tilbyder ét feed, hvor siden erklærer to. To alternative links
med samme type og samme titel ligner ét feed for sådan et værktøj, og det viser
det, det så sidst. Giv hvert sin egen titel; dette sites sider navngiver deres
med sitets navn efterfulgt af »(RSS)«, »(Atom)« eller »(JSON Feed)«.

## Læs mere

- [RFC 4287: The Atom Syndication Format](https://www.rfc-editor.org/rfc/rfc4287)
  — IETF-standarden med de krævede elementer, permanente id'er og datoer efter
  RFC 3339.
- [RSS 2.0 Specification](https://www.rssboard.org/rss-specification) — RSS
  Advisory Boards tekst til det frosne format, element for element.
- [JSON Feed Version 1.1](https://www.jsonfeed.org/version/1.1/) — den samme idé
  udtrykt i JSON, og hvad der ændrede sig fra version 1.0.
- [HTML Standard: link type alternate](https://html.spec.whatwg.org/multipage/links.html#link-type-alternate)
  — hvordan en side peger software hen til sine feeds.
- [W3C Feed Validation Service](https://validator.w3.org/feed/) — tjekker et
  RSS- eller Atom-feed ud fra dets adresse og forklarer hver advarsel.

<https://engineer.company/da/glossary/feed/>
