Next.js Discord

Discord Forum

Importing a CSS File from an Environment Variable in Next.js v14

Answered
Hashim posted this in #help-forum
Open in Discord
I'm using Next.js v14 and need to import a CSS file from a URL stored in an environment variable. Since environment variables cannot be directly used in static import statements, I'm looking for the best approach to dynamically load the stylesheet while ensuring it applies globally. I want to follow Next.js best practices and avoid any performance or hydration issues. What is the recommended way to achieve this?
Answered by Losti!
You can apply the link to the CSS file and also the preload if you see necessary, both are fine, well if everything is solved I'm glad to have helped! ((remember to mark the solution;3)
View full answer

42 Replies

and is that good?
      <head>
        <link
          rel="stylesheet"
          href={`${process.env.NEXT_PUBLIC_CDN_URL}/media/static/css/main.css`}
        />
      </head>

^ in layout.tsx
@Hashim
@Losti! Try with this: https://nextjs.org/docs/app/api-reference/functions/generate-metadata#resource-hints.
Thanks for the suggestion! Could you provide a code example of how to implement this?
Give me a minute
@Losti! Give me a minute
Alright, no rush. Thanks!
@Hashim
huozhi's comment has an example that will help you with your case.
@Losti! huozhi's comment has an example that will help you with your case.
So, I need to use this code in a client component right?
@Hashim So, I need to use this code in a client component right?
The documentation addresses that question! You should use the "use client" directive.
@Losti! The documentation addresses that question! You should use the "use client" directive.
my url is ${process.env.NEXT_PUBLIC_CDN_URL}/media/static/css/colors.css

and I try to use ReactDOM.preload
And didn't work
I used it in the page.tsx

Client console:
The resource http://localhost:3003/media/static/css/colors.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally
  ReactDOM.preload(
    `${process.env.NEXT_PUBLIC_CDN_URL}/media/static/css/colors.css`,
    { as: "style" }
@Hashim ts ReactDOM.preload( `${process.env.NEXT_PUBLIC_CDN_URL}/media/static/css/colors.css`, { as: "style" }
You need to specify it as a MIME Type, I assume you understood.

 ReactDOM.preload(
    '/https://cdn.com/bootstrap.min.css',
    { as: 'stylesheet' },
  )
@Hashim Click to see attachment
If we can use stylesheet in the ReactDOM why the docs didn't tell us to use it instead of saying "import stylesheets directly in the layout"
hmm Let me try it myself, I will make a project to test this feature.
this example works:

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      {/* with link tag in root layout */}
      <link
        rel="stylesheet"
        href="https://cdnjs.cloudflare.com/ajax/libs/Buttons/2.0.0/css/buttons.min.css"
        integrity="sha512-x8eU2Yx8Pd8XjWOTv+S/2jXGe586o6Ow722EaqGwG+4hkWaW1ZSAIMYUAY5QDyMglc9fPT0E1kZRIBwsdggtqg=="
        precedence="default"
        crossOrigin="anonymous"
        referrerPolicy="no-referrer"
      />
      {/* It is important to set precedence="default" or the next js will not allow it. */}
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        {children}
      </body>
    </html>
  );
}
Let's try the next one with ReactDOM.preload
@Hashim the old one I was using and Its working https://discord.com/channels/752553802359505017/1349251749302501547/1349254162600300555
Oh, I accidentally omitted it. If it works, you can leave it. Let me test if ReactDOM.preload works as expected and implement it if you're happy with it.
In my case, by not adding precedence="default" I got an error nextjs
I guess this error has not occurred to you so it must be an issue with a more recent version.
Works as expected for me
"use client";

import Image from "next/image";
import { preload } from "react-dom";

export default function Home() {
  preload(
    "https://cdnjs.cloudflare.com/ajax/libs/Buttons/2.0.0/css/buttons.min.css",
    { as: "style" }
  );
  return (
    ...page component
  )
}
@Losti! Works as expected for me tsx "use client"; import Image from "next/image"; import { preload } from "react-dom"; export default function Home() { preload( "https://cdnjs.cloudflare.com/ajax/libs/Buttons/2.0.0/css/buttons.min.css", { as: "style" } ); return ( ...page component ) }
In this case, it doesn't throw any errors because the other properties are not configured: integrity, precedence, crossOrigin, and referrerPolicy.

But you can add them if you need them.
@Hashim thank you
Just check carefully in the devtools (network part) to see if it downloads correctly without any problems.;3
@Losti! Just check carefully in the devtools (network part) to see if it downloads correctly without any problems.;3
I saw it and its there and got 200 OK but it didn't show up in the head tag and didn't get the colors
beacuse I need the rel to be stylesheet not preload
when I changed the rel to stylesheet in the dev tools I got the colors
@Hashim I saw it and its there and got `200 OK` but it didn't show up in the head tag and didn't get the colors
mb there It shows up in the head but as rel="preload" when I changed it to rel="stylesheet" everything works fine
Okay, I was right. You have to use both. Preloading causes the browser to download the resource in advance for later use, but it doesn't automatically apply it to the document. So, by using a link in the root layout with a stylesheet, as I showed you at the beginning, you would already be preloading the CSS and applying it with <link rel="stylesheet"/> atributte.
ye
You can apply the link to the CSS file and also the preload if you see necessary, both are fine, well if everything is solved I'm glad to have helped! ((remember to mark the solution;3)
Answer