javascriptnext.jsnextjs-15

Adding external stylesheet without using head tag


I am using Next JS version 15.3.2.

At present I am adding an external style sheet as follows in RootLayout file. It works.

But what is the proper way to add it in Next JS v15 now?

import type { Metadata } from 'next';
import './globals.css';
import React from 'react';

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
};

const RootLayout = ({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) => {
  return (
    <html lang="en">
      <head>
        <link
          rel="stylesheet"
          href="https://some-cdn.com/1.2.3/stylesheets/styles.min.css"
        />
      </head>
      <body>{children}</body>
    </html>
  );
};

export default RootLayout;

Looking at docs, this seems to be the option given but this looks more like a solution for before Nextjs v13.

https://nextjs.org/docs/messages/no-stylesheets-in-head-component

import { Html, Head, Main, NextScript } from 'next/document'
 
export default function Document() {
  return (
    <Html>
      <Head>
        <link rel="stylesheet" href="..." />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

Doesn't work.
Complains that I can't add a _document.js file outside pages folder which sounds outdated.

Nextjs been using app folder for some time now.
Pls advice the correct way to add external stylesheets. Thanks.


Solution

  • As Marianne said, your first example is already a valid solution. In Next JS documentation it's implied that in order to import external stylesheets there are two different takes on it:

    1. Next JS documentation :

    External Stylesheets published by external packages can be imported anywhere in the app directory, including colocated components:

    Example : app/layout.tsx

    import 'bootstrap/dist/css/bootstrap.css'
    
    export default function RootLayout({ 
      children, 
     }:{ 
      children: React.ReactNode 
     }) {
     return (
        <html lang="en">
          <body className="container">{children}</body>
        </html>   
      )
    }
    

    Good to know: In React 19, <link rel="stylesheet" href="..." /> can also > be used. See the React link documentation for more information.

    In React documentation they also explain that external stylesheets can also be imported with the typical <link rel="stylesheet" href="..." />

    1. React documentation :

    Linking to a stylesheet

    If a component depends on a certain stylesheet in order to be displayed correctly, you can render a link to that stylesheet within the component. Your component will suspend while the stylesheet is loading. You must supply the precedence prop, which tells React where to place this stylesheet relative to others — stylesheets with higher precedence can override those with lower precedence.

    Note When you want to use a stylesheet, it can be beneficial to call the preinit function. Calling this function may allow the browser to start fetching the stylesheet earlier than if you just render a component, for example by sending an HTTP Early Hints response.

    Example : App.js

    import ShowRenderedHTML from './ShowRenderedHTML.js';
    
    export default function SiteMapPage() {
      return (
        <ShowRenderedHTML>
          <link rel="stylesheet" href="sitemap.css" precedence="medium" />
          <p>...</p>
        </ShowRenderedHTML>   
      );
    } 
    

    TLDR; Your first solution :

    import type { Metadata } from 'next';
    import './globals.css';
    import React from 'react';
    
    export const metadata: Metadata = {
      title: 'Create Next App',
      description: 'Generated by create next app',
    };
    
    const RootLayout = ({
      children,
    }: Readonly<{
      children: React.ReactNode;
    }>) => {
      return (
        <html lang="en">
          <head>
            <link
              rel="stylesheet"
              href="https://some-cdn.com/1.2.3/stylesheets/styles.min.css"
            />
          </head>
          <body>{children}</body>
        </html>
      );
    };
    
    export default RootLayout;
    

    Is perfectly fine, as you are directly linking the cdn inside your component, as React suggests.

    I hope this is helpful!