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
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
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.
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).
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
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.