CSE 134B Web Client Languages
  1. Interaction
  2. Linking
  3. Links between documents
  4. Links Between Documents

Interaction · Linking 04

Links Between Documents

Most links on a page are never clicked, because nobody can click them. They sit in the head and tell the browser where the stylesheet is, which icon to show in the tab, which address is the real one, and which server to start talking to early. Others sit in the body and tell a search engine that a link was paid for, or tell a social network that two sites belong to the same person. The rel attribute is what says which kind of link each one is. This page covers the values that matter, who reads each one, and the corrections the old advice needs.

What a click does followed one link from the click to the next page. That page treated every link the same way, as an address and a request. This one asks a different question: what is the link for? HTML's answer is the rel attribute, short for relationship, which names how the current document relates to the one at the other end. The addresses themselves are the subject of URLs, and the request a followed link sends is covered in The request a link sends.

A plain link says only "there is another document at this address". Adding rel says what that document is to this one: the next chapter, the stylesheet, the author's profile, a paid advertisement. HTML calls each value a link type, and rel holds a list of them, separated by spaces, so one link can carry several: rel="ugc nofollow" is a link a visitor wrote that the site does not vouch for. The values are not case-sensitive, and their order does not matter.

The attribute appears in two places, and they behave very differently.

  • <link rel> in the head describes a relationship the browser, or some other program, acts on without anyone clicking. The person never sees these links. A <link rel="stylesheet"> is fetched and applied as the page loads; a <link rel="canonical"> is never fetched at all, but a search engine reads it. A <link> element has no content and no text, which is a good reminder that it is not for people.
  • rel on <a> (and on <area>, the link in an image map) describes a link a person can see and follow. Nothing happens until it is activated. The rel value tells the browser how to follow it, as noreferrer does, or tells a program reading the page what kind of link it is, as nofollow and next do.
Two kinds of link: head and bodyA page drawn as two parts. The head holds link elements for stylesheet, icon, canonical and preconnect; arrows go from them to the browser, which fetches or connects as the page loads, and to a search engine, which reads canonical. The body holds a elements with rel next and rel nofollow; an arrow from them goes to a person, who follows a link only by clicking it, and another to the search engine, which reads the rel values.the pagehead: no click, nothing visible<link rel="stylesheet"><link rel="icon"><link rel="canonical"><link rel="preconnect">body: links a person follows<a rel="next">Chapter 5</a><a rel="nofollow">…</a>the browserfetches, applies, connectsa search enginereads, never clicksa personfollows only on a clickas the page loadswhen activated
A <link> in the head is acted on as the page loads, by the browser or by other readers. An <a rel> in the body waits for a person, and its rel is read by programs too.

Which values go where

Not every value is allowed in both places. HTML's list of link types says, for each one, whether it may appear on <link>, on <a> and <area>, or both. The ones that load something for the current page are head-only, since a link in the body is only followed when clicked. The ones that change how a click is followed are body-only, since nobody clicks a <link>.

Allowed onLink types
<link> onlystylesheet, icon, manifest, canonical, preconnect, dns-prefetch, preload, modulepreload, prefetch, pingback, expect
<a> and <area> onlybookmark, tag; and, also allowed on <form>, nofollow, noopener, noreferrer, opener, external
Bothalternate, author, privacy-policy, terms-of-service; and, also allowed on <form>, help, license, next, prev, search

A <form> can carry some values too, because submitting a form is a navigation much like following a link: rel="noreferrer" on a form sends its submission with no Referer. Values that are not in HTML's table at all, such as me in section 8, are extensions, described in section 2.

Two corrections to older course material follow from this table. A <link rel="nofollow"> in the head means nothing; nofollow describes a link a person can follow, so it belongs on <a>. And rel="canonical" belongs only on <link> in the head (or in an HTTP header, section 9); on an <a> it is not valid HTML, and search engines do not treat it as a canonical address.

Every relationship on one page

The demo is a page that reports on itself. Its head holds a realistic set of <link> elements, its body holds a few links with rel, and a table lists every one with what the browser or a search engine does with it. With script running, the table is rebuilt from the live document, each href is shown resolved to a full URL, and the last column asks your browser, through relList.supports(), which link types it recognizes. Nothing on the page reaches a third party: the hosts it preconnects to do not exist, and the example.com addresses are descriptions that nothing fetches.

2. Where the values come from

The HTML standard defines the link types browsers act on, the ones in the table above, and says what each one does. They are not the only values in use. There are two other lists:

  • The IANA Link Relations registry is the list for the whole web, not only HTML. It was set up by the Web Linking specification, now RFC 8288, which also defines the HTTP Link header in section 9. It includes HTML's values and many others used by feeds, APIs and protocols: first and last for paging through API results, edit for the address that edits a resource, hub and self for feeds, and more. A value in this registry has the same meaning in an HTML rel, in an HTTP header and in a JSON API response.
  • The microformats wiki's "existing rel values" page is where the HTML standard sends anyone who wants to add a value for HTML. It records which values are proposed, in use or discontinued, and it holds community values such as me, used for identity in section 8, and shortlink, which some blogs use to advertise a short address for a post.

An invented value, rel="related-product" for example, does no harm, but nothing reads it except your own scripts, and a validator will flag it. When a project needs a relationship of its own, the convention from RFC 8288 is to use a full URL as the value, rel="https://example.com/rels/review", so it cannot collide with anyone else's. Most authors never need one: the registered values cover almost every real case, and using them means other people's software understands your links.

The old deck's list of "many possible relationship values" mixes all three sources without saying so. first is registered with IANA but HTML gives it no meaning; shortlink is a microformats value; pingback is HTML's, used by blogging software to notify other blogs that it linked to them. The useful habit is to check a value's source before relying on it, and the HTML standard's table first.

3. Resources the page uses

Three link types load something the current page needs. The browser fetches each one without a click, as soon as it reads the element.

stylesheet

<link rel="stylesheet"> is the link every page has. The browser fetches the CSS and, by default, waits for it before rendering anything, because showing the page unstyled and then restyling it would be worse. That makes stylesheets render-blocking, and it is why they belong in the head, early.

The media attribute limits a stylesheet to certain conditions. A stylesheet whose media query does not match is still downloaded, but at low priority, and it does not block rendering. That is the useful part: a print stylesheet costs a visitor on a screen almost nothing.

<link rel="stylesheet" href="/css/site.css"> <link rel="stylesheet" href="/css/print.css" media="print"> <link rel="stylesheet" href="/css/wide.css" media="(width >= 60rem)">

rel="alternate stylesheet" with a title offers a stylesheet the person can switch to, such as a high-contrast or large-print version. It is one of the web's oldest accessibility features, and one of the least supported: Firefox lists alternate stylesheets in its View menu under Page Style, and other browsers offer no way to choose one. A site that wants a theme switcher builds it with CSS custom properties and a control on the page, which works everywhere.

icon

<link rel="icon"> names the small image the browser shows in the tab, the bookmarks list, history and anywhere else it needs to represent the site. Browsers fetch it for their own interface, not for the page. With no icon link, they ask for /favicon.ico at the site's root, which is why server logs are full of 404s for that address on sites that never had one.

<link rel="icon" href="/favicon.ico" sizes="32x32"> <link rel="icon" href="/icon.svg" type="image/svg+xml" sizes="any"> <link rel="apple-touch-icon" href="/apple-touch-icon.png">
  • sizes says how big each icon is, so the browser can choose the best one for the place it is drawing. sizes="any" means the image scales, which is true of SVG.
  • An SVG icon is one small file that stays sharp at every size, and it can contain a prefers-color-scheme media query so the icon changes in dark mode. Chromium browsers and Firefox have used SVG icons for years; Safari added them in Safari 26, in 2025. A PNG or ICO fallback still covers older browsers.
  • apple-touch-icon is the image iOS uses when someone adds the page to their home screen. It is not in the HTML standard, but Apple's devices still read it. Make it a 180 by 180 pixel PNG with no transparency.

The old spelling rel="shortcut icon" still works, and HTML allows it for historical reasons, but shortcut has never meant anything. Write rel="icon".

manifest

<link rel="manifest"> points to a web app manifest, a small JSON file with the site's name, icons, theme color and the address to open when it is launched. Browsers read it when someone installs the site as an app, or adds it to a home screen.

<link rel="manifest" href="/site.webmanifest">

This corrects older course material, which said "manifest" was for the deprecated Application Cache. That was a different thing with the same name: a manifest attribute on the <html> element, which pointed to an AppCache file. AppCache has been removed from browsers and replaced by service workers. rel="manifest" is current, and it is how a page becomes installable.

4. canonical: which address is the real one

One page often has many addresses. All of these can return the same document:

https://shop.example/boots/trail-runner https://shop.example/boots/trail-runner/ https://www.shop.example/boots/trail-runner https://shop.example/boots/trail-runner?utm_source=newsletter&utm_medium=email https://shop.example/boots/trail-runner?color=blue&sort=price

A trailing slash, a www, tracking parameters added by a newsletter or a social network, filter and sort parameters added by the site's own scripts: each makes a new URL for the same content. A search engine that finds all five has to decide whether they are five pages or one, which to show in results, and where to count the links people made to each. Splitting the links between five addresses weakens all five.

<link rel="canonical"> answers the question from the page itself. Every version of the page names the same preferred address:

<link rel="canonical" href="https://shop.example/boots/trail-runner">
Duplicate addresses folded into one canonical addressFour boxes on the left, each a different address for the same page: with a trailing slash, with www, with utm tracking parameters, and with a sort parameter. Each has an arrow labeled rel canonical pointing to one box on the right, the canonical address, which a search engine indexes and shows, and to which it credits links made to any of the four./boots/trail-runner/www.shop.example/boots/……?utm_source=newsletter…?color=blue&sort=pricerel="canonical"canonical address/boots/trail-runnerindexed and shown;links to all four count here
Each duplicate address names the same canonical address, and a search engine folds them together. It treats the link as a strong hint, not a command.

Some rules make it work:

  • Use an absolute URL, scheme and host included. A relative canonical is resolved like any other link, and a mistake in it can name a page that does not exist.
  • Put one on the canonical page too, pointing at itself. A self-referencing canonical costs nothing, and it is what protects the page when someone links to it with tracking parameters attached.
  • Point only at a page with the same content. Search engines treat rel="canonical" as a strong signal, not an order; when the named page is clearly different, or returns a 404 or a redirect, they ignore it and choose for themselves.
  • One per page, in the head. Two that disagree give a search engine reason to ignore both.

A canonical link is not a redirect, and is not a replacement for one. A person who follows the duplicate address stays on it; only search engines fold the addresses together. When a page has truly moved, send a 301, as Redirects describes. And where the duplicates are of your own making, fix the cause as well: link to the final address with its trailing slash, and redirect the www or bare domain to the other. A canonical link handles the duplicates you cannot prevent, mostly the parameters other people add. Links you can trust looks at those tracking parameters from the reader's side.

5. alternate: the same page in another form

rel="alternate" says the linked document is another version of this one. What kind of version depends on the other attributes on the link.

Other languages: hreflang

With hreflang, an alternate is the same page in another language, or for another region. A search engine uses these links to show a person the version in their language. Every version lists every version, itself included, and one more for x-default, the page to show anyone whose language matches none of them, often a page that lets them choose:

<link rel="alternate" hreflang="en" href="https://shop.example/en/boots/"> <link rel="alternate" hreflang="es-MX" href="https://shop.example/es-mx/botas/"> <link rel="alternate" hreflang="fr" href="https://shop.example/fr/bottes/"> <link rel="alternate" hreflang="x-default" href="https://shop.example/choose-language/">
  • The value is a language code, optionally followed by a region: es, es-MX, zh-Hant. A region alone, such as MX, is not valid, because the language always comes first.
  • The links must go both ways. If the English page lists the Spanish one and the Spanish page does not list the English one, Google may ignore the pair, since otherwise any site could claim to be another site's translation.
  • The same information can be sent in an HTTP Link header, which works for PDFs and other files with no head, or in an XML sitemap. Google treats the three as equivalent.

These links help a search engine choose. They do not, and should not, send a person anywhere automatically; a site that redirects visitors by their Accept-Language header or their location takes away their choice. The Web Speaks Every Language makes that case. The visible language switcher on the page, made of ordinary links, is still needed, and each of its links can carry hreflang and lang too.

Other formats: feeds

With type, an alternate is the same content in another format. The common case is a feed: an RSS or Atom version of a blog, news page or podcast, which a feed reader can subscribe to.

<link rel="alternate" type="application/atom+xml" title="Course updates" href="/updates.atom"> <link rel="alternate" type="application/rss+xml" title="Lecture podcast" href="/podcast.rss">

A feed reader given the page's address finds the feed through this link, so people can subscribe without hunting for a feed URL. The title tells them apart when there are several. Browsers once showed a feed icon in the address bar for these links; none do now, but readers and many browser extensions still look for them, and they cost one line.

6. Performance hints

A browser learns what a page needs as it reads it. It finds the stylesheet in the head, then finds a font only when the stylesheet is parsed, then finds the image a script will insert only when the script runs. Each discovery waits for the one before it. Resource hints are <link> elements that tell the browser early about work it will need to do later, so it can start sooner. The broader subject, and how to measure whether a hint helped, is on Performance.

preconnect and dns-prefetch

Before a browser can request anything from a new host, it has to look up the host's address in DNS, open a TCP connection, and negotiate TLS. On a mobile network that is several round trips, easily a few hundred milliseconds, before the first byte of the request is sent. preconnect does those steps now, for a host the page will need soon:

<link rel="preconnect" href="https://cdn.example.com"> <link rel="preconnect" href="https://fonts.example.com" crossorigin> <link rel="dns-prefetch" href="https://stats.example.com">
What preconnect savesTwo timelines. In the first, without a hint, the browser parses the HTML and the CSS and only then discovers the font, after which it does a DNS lookup, a TCP connection and a TLS handshake before requesting the font. In the second, a preconnect link in the head starts the DNS, TCP and TLS steps while the HTML and CSS are still being parsed, so the font request goes out as soon as the font is discovered, earlier than in the first timeline.without a hintHTML, then CSSDNSTCPTLSfont requestwith preconnectHTML, then CSSDNSTCPTLSfont requeststarts as soon as the font is foundthe connectionwaits for discovery
A preconnect moves the connection's setup into time the browser would otherwise spend parsing. The request itself is unchanged; only the wait before it shrinks.
  • crossorigin matters. Fonts, and anything else fetched in CORS mode, use a separate connection from ordinary requests to the same host. A preconnect without crossorigin warms up the wrong one for a font.
  • Only preconnect to hosts the page will use within a few seconds. An open connection costs the browser and the server something, and browsers close an unused one after a short time. A handful of hosts is the useful limit; preconnecting to a dozen competes with the requests that matter.
  • dns-prefetch is the older, cheaper hint: the DNS lookup only. It is reasonable for hosts the page may need but cannot justify a full connection for, and as a fallback in front of a preconnect for very old browsers.
  • Your own host needs neither. The connection to the page's own origin is already open, because the HTML came over it.

preload

preload fetches a specific file now, at high priority, for the current page. It is for files the page certainly needs and the browser would find late: a font named only inside a stylesheet, a hero image set as a CSS background, a stylesheet a script will insert. This site's own head preloads its two main fonts:

<link rel="icon" href="/favicon.svg" type="image/svg+xml"> <link rel="stylesheet" href="/assets/vendor/vanilla-breeze/vanilla-breeze.css"> <link rel="stylesheet" href="/assets/css/powell-theme.css"> <link rel="preload" href="/assets/fonts/ibm-plex-sans-1.1.0/IBMPlexSans-Regular.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="/assets/fonts/ibm-plex-sans-1.1.0/IBMPlexSans-SemiBold.woff2" as="font" type="font/woff2" crossorigin> <link rel="stylesheet" href="/assets/css/styles.css">
  • as is required. It tells the browser what kind of file this is (font, style, script, image, fetch), which sets its priority and its Accept header, and lets the browser match the preloaded file to the request that uses it later. A preload without as, or with the wrong one, is fetched twice.
  • Fonts need crossorigin, even on the same origin, because fonts are always fetched in CORS mode. Without it the preloaded copy does not match the real request, and the font downloads twice. type lets a browser that cannot use the format skip it.
  • Preloading costs bandwidth that something else needed. Everything preloaded competes with the stylesheet, the HTML and the images the person is waiting for. Preload a few things the page cannot render well without, and nothing else. A file preloaded and then not used is pure waste, and Chrome says so in the console: a warning that the resource "was preloaded using link preload but not used within a few seconds".

Older material shows a trick for loading a stylesheet without blocking rendering: a preload with as="style" and an onload handler that switches it to rel="stylesheet". It works, but it shows the page unstyled first unless the critical CSS is inlined, and it depends on script. A stylesheet with a media query that does not match yet, or simply a smaller stylesheet, is usually the better fix.

prefetch and modulepreload

prefetch fetches a file at low priority, when the browser is idle, for a future navigation: the next page in a checkout, or the stylesheet of the page most people visit next. It is a guess, so it spends the person's data on something they may never use; use it where the guess is good. Safari does not support it. Making clicks faster describes speculation rules, the newer and more capable way to prefetch or prerender whole pages before a click, and they make <link rel="prerender">, which some old material still shows, obsolete: Chrome reduced it to a lighter kind of prefetch years ago.

modulepreload is preload for JavaScript modules. A module imports other modules, which import others, and the browser discovers each level only after fetching the one above. modulepreload fetches and parses a module ahead of time, and a page can list several to flatten the chain. It has been supported in every major browser since 2023 (Firefox 115, Safari 17).

HintWhat the browser doesFor
dns-prefetchLooks up a host's addressHosts the page may use
preconnectDNS, TCP and TLS to a hostA few hosts the page will use within seconds
preloadFetches a file now, high priorityFiles this page needs and would find late
modulepreloadFetches and parses a module nowModule chains this page needs
prefetchFetches a file when idle, low priorityThe likely next page (not in Safari)

Every hint is a hint. The browser may skip it under load, on a slow or metered connection, or when the person has turned on data saving. A page must work exactly the same without any of them.

7. Links that search engines read

Search engines rank pages partly by who links to them: a link is treated as a kind of recommendation. That made links worth faking, and three rel values exist so a site can say which of its links are not recommendations.

nofollow, ugc and sponsored

In January 2005, blogs were flooded with comment spam: automated comments whose only purpose was a link back to the spammer's site, planted on thousands of blogs to raise its ranking. Google proposed rel="nofollow", and Yahoo, MSN and the blogging company Six Apart announced their support the same week. A link with nofollow would earn the destination no ranking credit, so blog software could add it to every link in a comment and make comment spam worthless for ranking. It did not stop the spam, which was cheap to send anyway, but it became the standard mark for "this site does not vouch for this link".

In September 2019 Google added two more specific values, and changed what all three mean:

  • sponsored marks links that were paid for: advertisements, affiliate links, sponsorships. Search engines expect paid links to be marked, and treat unmarked ones as an attempt to buy ranking.
  • ugc, for user-generated content, marks links in comments, forum posts, reviews and anything else the site's visitors wrote.
  • nofollow remains for any other link the site does not want to vouch for, and for sites that do not bother to tell the cases apart.

The change was that all three became hints rather than rules. Google said it would use them as hints for ranking at once, and for deciding what to crawl and index from March 1, 2020. A nofollow link may still be followed and may still count. Older material describes nofollow as a directive, "don't pass link equity", and some still recommends it for keeping a page out of search results; neither is true now. To keep a page out of search results, use a noindex robots meta tag or header on that page.

<!-- In a comment a visitor wrote --> <a href="https://example.com/their-blog" rel="ugc nofollow">their blog</a> <!-- A paid placement or affiliate link --> <a href="https://store.example/boots?ref=cse134" rel="sponsored">Trail Runner boots</a>

The values can be combined, and the common combination is rel="ugc nofollow", so search engines that know only the older value still get the message. Comment and forum software adds them for you; when writing a site that accepts links from visitors, make sure it does.

noopener, noreferrer and opener

Three body values change how the browser follows a link, rather than describing it. What a click does covers them, so in brief:

  • noreferrer sends no Referer header with the request, and gives a new tab no opener. See What the Referer tells the next site.
  • noopener gives a page opened in a new tab no reference to the tab that opened it. Browsers have done this by default for target="_blank" links since 2021, so on links it is now harmless and unnecessary; older material still calls it critical. See The opener and tabnabbing.
  • opener asks for the old behavior back, for a page you trust.

8. Identity and documents

The remaining values describe how documents and the people behind them fit together. None changes what the browser does; they are for software that reads pages, and for people who read the source.

me: this is also the author

rel="me" says the linked page represents the same person, or organization, as this one. On its own that is just a claim, since anyone can link to anyone's profile. The claim becomes evidence when the other page links back with rel="me" too: two pages, each controlled by the person, each naming the other. This idea came from the IndieWeb, a community of people who publish on their own domains, and it has spread to other services.

Mastodon is the best-known use. Add your website to your Mastodon profile, put a rel="me" link to your profile on the website, and Mastodon checks the website; when it finds the link, it shows the site on your profile with a check mark. The website's link can be an <a> in the body or a <link> in the head, it must be in the HTML itself, not added by script, and the website's address must be HTTPS.

<!-- A visible link, in the footer of a personal site --> <a href="https://social.example/@cse134b" rel="me">Mastodon</a> <!-- The same claim in the head, invisible --> <link rel="me" href="https://social.example/@cse134b">
rel me: verification by links in both directionsOn the left, a personal website, cse134b.example, containing a link with rel me to a social profile. On the right, the social profile, social.example slash at cse134b, listing the website. An arrow goes from the website to the profile, labeled rel me. A second arrow goes from the profile back to the website, labeled the profile lists the site. Below, a note: the service fetches the website, finds the rel me link back, and shows the site as verified. Neither page alone proves anything.cse134b.examplethe person's own site<a rel="me" href="…/@cse134b">social.example/@cse134bthe profilewebsite: cse134b.examplerel="me"the profile lists the sitethe service fetches the site, finds the link back, and marks it verified;either link alone proves nothing
Verification with rel="me" needs links both ways. Only someone who controls both pages can make them point at each other.

Notice what this does and does not prove. It proves that whoever controls the website also controls the profile. It says nothing about who that is. A check mark on a profile verified this way means "this person runs that website", which is only as trustworthy as the website.

author, license, help and search

  • author links to information about the page's author: a profile page, a staff page, a mailto: address. On an <a> in an article's byline, it marks which link is the author's.
  • license says the main content of the page is covered by the linked license. A Creative Commons footer link with rel="license" lets search engines and tools filter content by license. HTML says not to use rel="copyright", an old synonym.
  • help links to help for the context it appears in. On a form field's "What is this?" link, it marks that link as help for the field.
  • search points to a way to search the site. With type="application/opensearchdescription+xml" it points to an OpenSearch description, a small XML file that tells a browser how to build a search URL for the site, so the browser can offer the site as a search engine in its address bar. Firefox offers to add it.
  • privacy-policy and terms-of-service mark the links to those documents, so software can find them.
  • bookmark marks a permalink for the section or article that contains it; tag marks a link to a tag page that describes the current document; external marks a link to another site, which a stylesheet can select with a[rel~="external"] to add an icon.

next and prev

rel="next" and rel="prev" mark the documents before and after this one in a series: pages of search results, chapters of a book, lessons in a course. They are still valid HTML in both places, and this page's own previous and next links at the bottom use them.

For several years they were also how a site told Google that a set of pages was one series. In March 2019, Google said it had not used them for indexing for years, and had not told anyone. Its advice since is to make each page in a series stand on its own and to link the pages to each other with ordinary links. Older course material still presents them as a search signal; that part is out of date. They remain useful as a description: some browser extensions and assistive tools use them to move through a series, and they cost nothing.

Everything a <link> element says can also be said by the server, in an HTTP Link response header, defined by the same RFC 8288 as the registry. The target goes in angle brackets, and the attributes follow as parameters:

Link: <https://shop.example/boots/trail-runner>; rel="canonical" Link: </fonts/plex-600.woff2>; rel=preload; as=font; type="font/woff2"; crossorigin Link: <https://cdn.example.com>; rel=preconnect

The header has two advantages over the element. It works for responses that have no head: a PDF can name its canonical address, or its translations, only this way. And the browser sees it as soon as the headers arrive, before it has read a byte of HTML, which makes it the earliest possible place for a hint. Search engines read canonical and alternate from it; browsers act on the performance hints in it.

103 Early Hints

A server often needs time before it can send the page: it queries a database, renders a template, calls another service. During that wait the browser has nothing to do. 103 Early Hints is an informational response a server can send first, while it is still working, carrying Link headers for the preconnects and preloads the page will need. The browser starts those connections and downloads, and the real response follows.

HTTP/2 103 link: </css/site.css>; rel=preload; as=style link: <https://cdn.example.com>; rel=preconnect HTTP/2 200 content-type: text/html …

Chrome and Edge act on both preconnect and preload hints in a 103, for top-level page loads, since version 103. Firefox supports both, and Safari supports preconnect. Browsers act only on the first 103 for a request, and ignore it when the request ends in a redirect to another origin. In practice a 103 is usually sent by a CDN, which learns from past responses which Link headers a page sends and replays them early, so the site does not write any code for it. Before the First Byte follows the wait that Early Hints fills.

10. Summary

ConceptKey points
relA space-separated list of link types naming how this document relates to the linked one. <link rel> in the head is acted on without a click; rel on <a> and <area> describes a link a person follows. Some values are allowed only in one place: nofollow is body-only, canonical head-only.
Where values come fromThe HTML standard for what browsers do; the IANA Link Relations registry (RFC 8288) for the whole web; the microformats wiki for proposed and community values. A private relationship uses a full URL as its value.
Resourcesstylesheet (render-blocking; media makes non-matching ones low priority; alternate stylesheets are Firefox-only). icon with sizes, SVG with sizes="any" (Safari since 26), apple-touch-icon at 180 by 180. manifest is the web app manifest, not AppCache.
canonicalOne absolute, preferred address for a page with many: slashes, www, tracking and sort parameters. Self-referencing on the canonical page. A strong hint to search engines, not a redirect.
alternateWith hreflang: language versions, listed on every version, both ways, plus x-default. With type: RSS and Atom feeds for feed readers.
Performance hintspreconnect (a few hosts, crossorigin for fonts), dns-prefetch, preload (with as; fonts need crossorigin; over-preloading steals bandwidth), modulepreload, prefetch (not Safari). Speculation rules replace prerender. All are hints.
Search engine valuesnofollow (2005, against comment spam), ugc and sponsored (2019). All three are hints since 2019 for ranking and since March 2020 for crawling. Use noindex, not nofollow, to keep a page out of results.
Following valuesnoreferrer, noopener (the default for target="_blank" since 2021), opener. Covered in What a click does.
Identity and documentsme verifies by links both ways (IndieWeb, Mastodon). author, license, help, search (OpenSearch), privacy-policy, bookmark, tag, external. next and prev are valid, but Google said in 2019 it no longer uses them.
Link headerThe same relationships sent by the server; the only way for a PDF. 103 Early Hints sends preconnects and preloads before the page is ready.