Is it possible to disable ssr on some pages using Next js? For example, I have a page with a product description on which I use ssr for SEO but I also have a page with a list of items or products which I can filter and for that page, I don't want to use ssr because this page generates dynamically every time, how can I disable ssr on this page?
-
if you use material ui, there is a `NoSsr` component you can use directly out of the box – guest Nov 03 '21 at 06:59
9 Answers
The dynamic()
function can also be used without a dynamic import:
// components/NoSsr.jsx
import dynamic from 'next/dynamic'
import React from 'react'
const NoSsr = props => (
<React.Fragment>{props.children}</React.Fragment>
)
export default dynamic(() => Promise.resolve(NoSsr), {
ssr: false
})
Anything wrapped in this component will not be visible in the SSR source. For example:
// inside the page you want to disable SSR for
import NoSsr from "components/NoSsr";
Contact me at <NoSsr>email@example.com</NoSsr>

- 5,419
- 3
- 35
- 48

- 2,296
- 2
- 18
- 39
-
2
-
3
-
One limitation though: it probably have other side effects regarding the way code is loaded. A pure React solution might be sufficient (as described in anwser https://stackoverflow.com/a/57512843/5513532 for instance) – Eric Burel Feb 18 '21 at 09:55
Lazy load the component and disable SSR: https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr
import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(() => import('../components/List'), {
ssr: false
})
export default () => <DynamicComponentWithNoSSR />

- 1,793
- 1
- 11
- 12
-
1If there are children inside that no ssr element, what happens? I need the no ssr for my toplevel element that holds other children, would that affect my SEO and performance? – Nikola-Milovic Sep 07 '21 at 07:33
-
3
-
This also will not work if the component has named exported variables – Jamie Hutber Sep 28 '22 at 12:55
-
Isn't `export default () =>
` the same as `export default DynamicComponentWithNoSSR`? Anyway, you saved my day, good precise answer! – Page not found Jun 13 '23 at 11:54
This will disable next.js SSR, put this on your _app.tsx
import type { AppProps } from "next/app";
import dynamic from "next/dynamic";
import React from "react";
const App = ({ Component, pageProps }: AppProps) => {
return <Component {...pageProps} />;
};
export default dynamic(() => Promise.resolve(App), {
ssr: false,
});

- 7,360
- 4
- 27
- 31
-
8That disables SSR for the whole project and the advantages of SSR like SEO-Friendly pages are lost. (Just to take in mind) – Herii Sep 02 '22 at 20:20
-
1
-
1It's not necessary to do this for the entire project. You can also use this for specific pages – Eugene P. Nov 14 '22 at 15:17
-
This is a late answer, but in case anyone runs into this:
const isServer = () => typeof window === `undefined`;
const Page = () => isServer() ? null : (
<>
<YourClientSideComponent />
</>
);
This is on the "page" level. isServer()
prevents rendering of anything while on the server side. You could, if you wanted to, prevent ssr on the component level also:
const isServer = () => typeof window === `undefined`;
const Page = () =>(
<>
{ !isServer() && <YourClientSideComponent /> }
</>
);

- 506
- 4
- 13

- 792
- 5
- 14
- 27
-
Is the "." before `!isServer` intentional? That is invalid JavaScript syntax. – Dawson B Jan 20 '20 at 02:56
-
I had it working in the Next.js project with styled-components in it, but doesn't work always as required. Not sure why!! The accepted solution is best fit – Vaishak Mar 13 '20 at 07:35
-
3This will create a mismatch between server-render and client-render, this doesn't actually disable the render. – Eric Burel Feb 18 '21 at 09:50
We can also use react-no-ssr React component.
Let's say Comments is our client only component. Now we need to render it only on the client. Here's how we do it.
import React from 'react';
import NoSSR from 'react-no-ssr';
import Comments from './comments.jsx';
const MyPage = () => (
<div>
<h2>My Blog Post</h2>
<hr />
<NoSSR>
<Comments />
</NoSSR>
</div>
);

- 13,954
- 24
- 68
- 103
Here's a solution that i just came up with based on the something mentioned in the React docs: https://reactjs.org/docs/react-dom.html#hydrate
class ClientOnly extends React.Component {
state = {
isClient: false,
};
componentDidMount() {
this.setState({
isClient: true,
});
}
render() {
const { isClient } = this.state;
const { children } = this.props;
return isClient ? children : false;
}
}
You can then wrap any component / block with this and it won't get rendered on the server. e.g.
<ClientOnly>You're logged in as {name}</ClientOnly>
This also prevents the following React.hydrate warning "Warning: Expected server HTML to contain a matching in ."

- 110,530
- 99
- 389
- 494

- 95
- 1
- 5
-
1Equivalent with hooks would look like this I think: `const useClientCheck =() => { const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true)}, []); return isClient }` – Eric Burel Feb 18 '21 at 09:51
In @refactor answer, the react-no-ssr
is not working for some typescript issue.
I just wrote a very simple NoSSR component as below:
import { ReactNode, useEffect, useLayoutEffect, useState } from 'react'
const DefaultOnSSR: React.FC = () => null
export const NoSSR: React.FC<{ children: ReactNode; onSSR?: ReactNode }> = ({ children, onSSR = <DefaultOnSSR /> }) => {
const [onBrowser, setOnBrowser] = useState(false)
useLayoutEffect(() => {
setOnBrowser(true)
}, [])
return <>{onBrowser ? children : onSSR}</>
}
and can be used anywhere if you want to avoid SSR like below:
const MyPage = () => (
<div>
<h2>My Blog Post</h2>
<hr />
<NoSSR>
<Comments />
</NoSSR>
</div>
);

- 6,037
- 4
- 33
- 52
-
This solution gave me "Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format." warning – Mahmoud Sep 29 '22 at 08:07
Based entirly on the answer by Erik Hofer, you can create an HOC to wrap your pages or other components in.
import dynamic from 'next/dynamic';
import React from 'react';
const withNoSSR = (Component: React.FunctionComponent) => dynamic(
() => Promise.resolve(Component),
{ ssr: false },
);
export default withNoSSR;
Then use as:
import React from 'react';
import withNoSSR from './withNoSSR';
function SomePage() {
return (
<div>Only renders in the browser</div>
);
}
// wrap with HOC on export
export default withNoSSR(SomePage);

- 2,849
- 4
- 30
- 39
Another and I believe the simplest solution is to just use process.browser
, which will only be true when ran on client side.
<div>
{
process.browser && <Hidden />
}
</div>

- 525
- 7
- 23