Importing a css file for a different page in React - css

I am having an issue where when I try and import css onto each page, it will appear on all pages instead of just one. I have my CSS importing in _document.js
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html>
<Head>
<link rel="stylesheet" href="/styles/index.css" />
<link rel="stylesheet" href="index.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/fontawesome.min.css" integrity="sha512-xX2rYBFJSj86W54Fyv1de80DWBq7zYLn2z0I9bIhQG+rxIF6XVJUpdGnsNHWRa6AvP89vtFupEPDP8eZAtu9qA==" crossOrigin="anonymous" referrerPolicy="no-referrer" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
and I want to know how I can import this CSS on a per-page basis, instead of having all css files on all pages. I have tried importing the css inside of each JS file, but it seems to want to go to /pagehere/styles/settings.css instead of /styles/settings.css even when I put import '../styles/settings.css'. Thanks.

Remove the <Link>s and try using import '../../stryles/settings.css' instead.

Related

How to get locale in nextjs in document component?

I want to set locale in script google map like this:
<script defer src={`https://maps.googleapis.com/maps/api/js?key=key&libraries=places&language=${locale}`}/>
but how can i get to locale in Document nextJS?
useRouter doesnot work in Document component.
export default function Document() {
return (
<Html>
<Head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<script defer src={`https://maps.googleapis.com/maps/api/js?key=key&libraries=places&language=${locale}`}/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
You can access locale in this.props.locale.
In my project this locale uses in this case:
<Html lang={this.props.locale}>
/....
I use class component in _document.
In your variant you can access locale just in props.
import { Html, Head, Main, NextScript } from "next/document";
export default function Document(props: DocumentProps) {
return (
<Html lang={props.locale}>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
It works if you already add i18n config, and inject it to next config.
https://codesandbox.io/p/sandbox/musing-noether-7loye1?file=%2Fpages%2F_document.tsx&selection=%5B%7B%22endColumn%22%3A9%2C%22endLineNumber%22%3A11%2C%22startColumn%22%3A9%2C%22startLineNumber%22%3A11%7D%5D

Integrating ShareThis with Next.js

Has anyone tried to integrate ShareThis with Next.js?
I'm getting "Hydration failed because the initial UI does not match what was rendered on the server." and this, I have ascertained, is down to the inclusion of the ShareThis script tag.
I'm not sure what I need to do in order to resolve this error.
This is my _document.tsx file, containing the offending script tag:
import { Html, Head, Main, NextScript } from "next/document";
const Document = () => (
<Html>
<Head>
<script
type="text/javascript"
src={`https://platform-api.sharethis.com/js/sharethis.js#property=${process.env.NEXT_PUBLIC_SHARETHIS_PROPERTY_ID}&product=sop`}
async
defer
></script>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
export default Document;
Of course, the NEXT_PUBLIC_SHARETHIS_PROPERTY_ID variable from my .env file is being correctly populated.
You should be using next/script to load 3rd party scripts like ShareThis. Here's their documentation https://nextjs.org/docs/basic-features/script
Make sure to apply the <Script src="" /> component OUTSIDE of the next/head component, either above of below it.
Hope this helps.

next script does not work inside _document.js file nextjs

I have a nextjs project. I want to load two scripts using next/script inside _document.js.But when I place the Script tags into the body tag in _document.js, my scripts do not execute. I implemented according to the next/script guideline.What may be the issue here?
My code:
import { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";
export default function Document() {
return (
<Html>
<Head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
</Head>
<body>
<Main />
<NextScript />
<Script
strategy="beforeInteractive"
src="src"
type="text/javascript"
charSet="UTF-8"
data-domain-script="id"
/>
<Script
strategy="beforeInteractive"
type="text/javascript"
dangerouslySetInnerHTML={{
__html: `
some js code
`,
}}
/>
</body>
</Html>
);
}
Initially in next/script api reference section, it was documented to use Script tags in _document.js with beforeInteractive strategy. But now their api reference has been updated and you must use Script tag with beforeInteractive strategy in pages/_app.js.
API Reference Link
Quote from next/script api reference
beforeInteractive scripts must be placed inside pages/_app.js and are designed to load scripts that are needed by the entire site (i.e. the script will load when any page in the application has been loaded server-side).

Any nextjs example where I need to use _document over _app

It seems I can do everything that I need to do in both _app and _document for my application just in _app like
// _app.tsx
import Head from 'next/head';
export default function App({ Component, pageProps }) {
return (
<>
<Head>
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no"
/>
<title>Payment</title>
</Head>
<Component {...pageProps} />
</>
);
}
Then when should I use _document necessarily? I found _document pointless because:
I shouldn't place viewport meta tags in _document as nextjs compiler warnings about it. (I thought _document is a good place for markups in head because _document gets called only once on server-side and not on client-side) If I can't place everything of a kind like head markup in one place, I'd like to avoid using that way.
You'll need _document if you want to customize a page's <html> and <body> tags. For example...
Adding the global lang attribute:
<Html lang="en">
Adding custom styles:
<body className="bg-white">
_document is where you put third party links and scripts
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
render() {
return (
<Html>
<Head>
<link
href="https://fonts.googleapis.com/css2?family=Inter&display=optional"
rel="stylesheet"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
If you are using styled components you need to configure it in _document.jsx file.
https://github.com/massaaki/nextjs-with-styled-component/blob/main/src/pages/_document.tsx

Can you have multiple, additive 'HEAD' elements in NextJS?

I want to be able to have a 'master' HEAD element in _document.js and for certain pages have an additional HEAD element that adds to what is in the 'master'. From https://nextjs.org/docs/api-reference/next/head it would seem that this is possible.
However, when searching for the answer in Stack Overflow, I found this post, which seems to indicate that this can lead to unexpected results.
If I can't have multiple HEAD elements, do I need to pass data from the individual page through getInitialProps?
You can simple import next/head into any page/component when you need to do something with it
Example:
import Head from 'next/head'
function IndexPage() {
return (
<div>
<Head>
<title>My page title</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<p>Hello world!</p>
</div>
)
}
export default IndexPage
and also have a default Head within _document.js
import Document, { Head, Main, NextScript } from 'next/document';
export default class MyDocument extends Document {
render() {
return (
<html lang="en">
<Head>
<link rel="shortcut icon" href="/favicon.ico" />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
);
}
}
I am not experiencing any issue so far.
Something to remember though:
The contents of head get cleared upon unmounting the component, so make sure each page completely defines what it needs in head, without making assumptions about what other pages added.

Resources