8

The documentation for using appDir on Next.js 13.4 states the following:

Step 3: Migrating next/head

In the pages directory, the next/head React component is used to manage HTML elements such as title and meta. In the app directory, next/head is replaced with the new built-in SEO support.

But the next/head component was able to add non-SEO tags too. In particular, I want to add <link rel="..."> tags. How does one accomplish this if the metadata mechanism doesn't seem to support link tags (just custom <meta> tags)?

I can't add the tags directly to the root layout because there are tags that are only supposed to live on the website home page. I could conditionally add the tags to the root layout if the layout was aware of the current route but it doesn't seem to work with SSG.

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
villasv
  • 6,304
  • 2
  • 44
  • 78

4 Answers4

4

I think the document covered how to add <link rel="..."> tags, you just need to follow their predefined way.

https://nextjs.org/docs/app/api-reference/functions/generate-metadata#manifest https://nextjs.org/docs/app/api-reference/functions/generate-metadata#icons

// in your app/page.tsx export metadata
export const metadata = {
  manifest: 'https://nextjs.org/manifest.json',
  icons: {
    icon: '/icon.png',
    shortcut: '/shortcut-icon.png',
    apple: '/apple-icon.png',
    other: {
      rel: 'apple-touch-icon-precomposed',
      url: '/apple-touch-icon-precomposed.png',
    },
  },
};

export default function Page() {
    ... // your code here
}
<link rel="manifest" href="https://nextjs.org/manifest.json" />
<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>

verified with next@13.4.1

linxie
  • 1,849
  • 15
  • 20
  • Wow, this actually worked. The way to get a custom `rel="..."` on a `` tag is to pretend that I'm adding an icon... well, nice catch! – villasv May 10 '23 at 22:35
0

What about file based metadata?

Once a file is defined, Next.js will automatically serve the file (with hashes in production for caching) and update the relevant head elements with the correct metadata, such as the asset's URL, file type, and image size.

You MUST add a global.css file in app folder, ... ad import it inside your layout. This is working for me.

.redtext { color: red;}
import './foo.css'

export const metadata = {
    title: 'mamma mia'
}

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                <div className="redtext">test rosso</div>
                <div id="root-container">{children}</div>
            </body>
        </html>
    )
}
sensorario
  • 20,262
  • 30
  • 97
  • 159
  • Which file using which format, exactly? From the docs, it seems file based metadata means dropping a file with a specific name and letting Next.js infer the meta tags for it. For example, adding a `app/opengraph-image.jpg` file will generate the `` tags. But there seems to be no file that I can add that would generate `` tags. – villasv May 06 '23 at 22:34
  • Tried adding just a css file? – sensorario May 07 '23 at 12:26
  • @sensorario i think he's referring to general link tags, that can be used to load fonts and other types of files. – Tochi Bedford May 07 '23 at 14:42
  • @sensorario I don't want a link to a css file so no point in just adding a CSS file. The `` tag defines the relationship between the current document and an external resource and that's what I'm trying to accomplish, I'm not trying to load scrips or fonts, but for general linking of resources. – villasv May 08 '23 at 03:06
0

Trying Next 13 for the first time right now too, and in the default layout.tsx file, I placed my link tags like so:

<html lang="en">
  <head>
    <link rel="preconnect" href="xyz.com" />
  </head>
  <body >{children}</body>
</html>

and my link tags show up correctly in the browser. This also seems to work correctly with the exported metadata object, so I left the rest of the metadata tags in the new recommended format.

Tochi Bedford
  • 354
  • 1
  • 9
  • Yeah, I guess this seems to be the only way for now. But adding this to the layout file used for the root route will also add it to all subpages, which isn't ideal, specially for the semantics of link tags. – villasv May 08 '23 at 03:08
  • oh, could you explain how it could be a problem when the link tags also show up in sub pages? I don’t think it is, especially if your goal is just to link to some external resource. even if the goal is to preload some resource, will it really kill semantics when you have this same link tag in a sub page that doesn’t need it? – Tochi Bedford May 08 '23 at 13:14
  • It's not about performance or loading resources. The problem is just semantics. I'm using link tags to create semantic association between different resources and these are page dependant. – villasv May 08 '23 at 17:20
  • Note that the [](https://html.spec.whatwg.org/dev/embedded-content.html#the-img-element) tag does not use and does not need a closing slash and never has in any HTML specification. – Rob May 09 '23 at 07:17
  • Sorry. I meant the `` tag – Rob May 09 '23 at 08:52
  • @Rob, true! although without it, it throws an error in React TSX, which was my environment at the time. – Tochi Bedford May 09 '23 at 09:46
  • You would think the React people would give a slight glance at the standard, at least, when creating such things. – Rob May 09 '23 at 12:34
0

I followed typescript type

import type { Metadata } from 'next'

If you go to Metadata interface (in vscode press "ctrl" and click on "metadata"), it has

 archives?: null | string | Array<string>;
/**
 * The assets link rel property.
 * @example
 * ```tsx
 * "https://example.com/assets"
 * <link rel="assets" href="https://example.com/assets" />
 * ```
 */

archives is not only property. if you check the Metadata interface, you can find a suitable option for your need

robots?: null | string | Robots;

//The canonical and alternate URLs for the document.
alternates?: null | AlternateURLs;

icons?: null | IconURL | Array<Icon> | Icons;
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • Nice catch! That's _almost_ what I needed. The thing is, the `` tag I wanted uses `rel=` something else other than `assets`, so it doesn't fit my need :-/ – villasv May 09 '23 at 03:18
  • that is just an example form docs. try it on your app. it can be anything. its type is `string`, not something specific that used only for "assets" – Yilmaz May 09 '23 at 03:19
  • Good CTA. I just tested it and it seems for each `string` passed Next.js generates `` (amusingly, it doesn't match the documented example, because it's the docstring of the other prop `assets`, which works the same way). – villasv May 09 '23 at 03:24