Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a mechanizm to disable SSR #4381

Closed
cherniavskii opened this issue May 15, 2018 · 32 comments
Closed

Provide a mechanizm to disable SSR #4381

cherniavskii opened this issue May 15, 2018 · 32 comments

Comments

@cherniavskii
Copy link
Contributor

Is your feature request related to a problem? Please describe.
The problem is that sometimes server load is high because of SSR. Right now it can be optimized by turning off SSR for some components, but it doesn't solve the problem fully.

Describe the solution you'd like
Ideally - to provide something like Electrode has: Server Side Rendering Modes.

Electrode constantly monitors the performance of your app and turns off server-side rendering if app performance is degrading.

Describe alternatives you've considered
An alternative (and probably more elastic) solution would be to provide SSR Modes without any performance monitoring.

Additional context
I know that right now next.js is tightly coupled with SSR, but SSR modes should help a lot at large scale.

P.S. Thanks you guys for working on such a great project ;)

@mauvew

This comment has been minimized.

@HaNdTriX HaNdTriX mentioned this issue Aug 22, 2018
@soroushchehresa

This comment has been minimized.

@mzaidse

This comment has been minimized.

@Zertz
Copy link
Contributor

Zertz commented Feb 27, 2019

While not built in, react-no-ssr works quite well for that purpose!

@timneutkens timneutkens added future and removed future labels Mar 5, 2019
@gautamsi
Copy link

proposal: Checking for a static property on default import with { ssr: false} should make this dynamic component without ssr.

This will greatly help in rapid development while I figure out if component can be dealt with ssr or not.

@farhadniaz
Copy link

We should provide a flag in Nextjs config to provide Universal and SPA mode. this is very important .
After working with Nextjs in different projects i find out Nextjs has many powerful aspects but it suffers from community support .

@timneutkens
Copy link
Member

@farhadniaz I'm not sure what you're asking for 🤔 You can already choose to not render the tree on the server using something like react-no-ssr or a React hook.

@farhadniaz
Copy link

@timneutkens react-no-ssr not the answer . I please look at the NUXT.js SPA mode and you will find out what i mean

@timneutkens
Copy link
Member

timneutkens commented Aug 9, 2019

I'm not going into this further as it's off-topic to this issue, this issue is related to backoff under load. Nuxt's SPA mode is quite the same as just opting out of SSR, except it's a flag, which in general you don't want, as you might want to prerender part of the skeleton.

@farhadniaz
Copy link

@timneutkens so you mean in _app.js we have to use react-no-ssr as root component?

@nguyenvanhoang26041994

This comment has been minimized.

@sophister
Copy link

Does Next.js provide such mechanizm now? I can't find any document related to this.

@benalexb
Copy link

Bumping this issue up, as it has become quite common these days to use Next as a static site generator. Of course, one can always build, export, and serve the static website, but that comes at a cost (live-reloading and other development sugar).

There are other motivations too behind the ability to disabled SSR, such as to quash react's warning when the server-side rendered DOM does not match the client's, which is very common on a static website as there is no pre-loaded data.

@Hubro
Copy link

Hubro commented May 21, 2020

I want to be able to temporarily disable server side rendering so I can debug a crash in my browser with dev tools rather than trying to figure out from the dev server log what happened. Installing a new dependency and wrapping my code in a new element seems like an excessive requirement to achieve this :/

I just want something like next --no-ssr until I'm done debugging the error, then I remove the flag again. Why would something like that be problematic to implement? Couldn't you even just include react-no-ssr by default and wrap the topmost element in <NoSSR> if the flag is provided?

@lostfictions
Copy link
Contributor

react-no-ssr won't help if you have side-effectful imports that rely on the DOM. But you can use next's built-in dynamic import functionality instead, and move your page root (or whatever subset of it can't run on the server) into a different file:

import dynamic from 'next/dynamic'
const App = dynamic(() => import('../components/App'), { ssr: false })
export default () => <App />

This works well enough for me as someone making a static site that relies on eg. WebGL and DOM APIs, but who still wants to take advantage of Next's sensible defaults and configurability (rather than, say, trying to puzzle out which variant of create-react-app override packages is still maintained).


This maybe also suggests a sketch for folks who want to toggle SSR with a switch on the command line or disable it in development and enable it during build for static export:

import dynamic from 'next/dynamic'
const App = dynamic(() => import('../components/App'), {
  ssr: process.env.NEXT_PUBLIC_SSR_ENABLED
})
export default () => <App />

Then, on the command-line:

NEXT_PUBLIC_SSR_ENABLED=false npm run dev

That said, I personally think it would still be great if Next added better support for non-SSR scenarios -- as mentioned in this thread, there's still lots of idiosyncrasies for people using Next for fully static (non-hybrid) static site generation, etc.

@renatodex
Copy link

Dynamic imports really make our life easier, but if you think about Canvas integration, there are a few issues using the SSR approach. I've tried to use PhaserJS before, which relies on Dom at the very moment it is imported, and I never could make it load as a component.

Of course, Canvas frameworks like Phaser don't really play well with React and Virtual Dom, but even a loose abstraction is hard to assemble with SSR.

@timneutkens
Copy link
Member

@renatodex you can dynamically import files on client-side using import()

@renatodex
Copy link

Hey @timneutkens !
I don't want to distort the main goal of this Issue, so I've posted my failed experiment with Phaser as a new Issue in the Issues of NextJS.
#13417
Take a look when you have time!

@eric-burel
Copy link
Contributor

Not sure if it has been mentioned before, but easy and global disable of SSR is useful in the context of e2e/integration testing.

Cypress provides mock for requests triggered by the browser, but it's much more difficult to mock server side queries, especially when they hit the same origin. There's not much recipe to handle this on the web, so the easiest path is to disable SSR when running e2e tests.

@jgoux
Copy link

jgoux commented Jun 26, 2020

react-no-ssr won't help if you have side-effectful imports that rely on the DOM. But you can use next's built-in dynamic import functionality instead, and move your page root (or whatever subset of it can't run on the server) into a different file:

import dynamic from 'next/dynamic'
const App = dynamic(() => import('../components/App'), { ssr: false })
export default () => <App />

This works well enough for me as someone making a static site that relies on eg. WebGL and DOM APIs, but who still wants to take advantage of Next's sensible defaults and configurability (rather than, say, trying to puzzle out which variant of create-react-app override packages is still maintained).

This maybe also suggests a sketch for folks who want to toggle SSR with a switch on the command line or disable it in development and enable it during build for static export:

import dynamic from 'next/dynamic'
const App = dynamic(() => import('../components/App'), {
  ssr: process.env.NEXT_PUBLIC_SSR_ENABLED
})
export default () => <App />

Then, on the command-line:

NEXT_PUBLIC_SSR_ENABLED=false npm run dev

That said, I personally think it would still be great if Next added better support for non-SSR scenarios -- as mentioned in this thread, there's still lots of idiosyncrasies for people using Next for fully static (non-hybrid) static site generation, etc.

@lostfictions @timneutkens Does this strategy allows to use something like React-router and being able to export the app as a single index.html + multiple js files (code-splitted)?
I'm in the same boat as you @lostfictions , I want to take advantage of Next.js extendable configuration in place of CRA, but I don't want to have a server coupled with my SPA.
I'm aware of next export but I need a single html entry point to my app (in order to wrap it with capacitor for mobile distribution).

@verekia
Copy link

verekia commented Jul 30, 2020

It would be very convenient for debugging purposes to have this mode option, similar to what Nuxt has. But to go even further, it would also be convenient to have an ssr-only mode. This is very useful to debug universal authentication for instance. You can make sure everything works during client navigation only, and during server navigation only. I used to do this when I made my own isomorphic apps without Next and I really miss being able to do that.

  • next dev --mode=spa-only
  • next dev --mode=ssr-only
  • next dev --mode=universal (default)

Something like that.

It was not that complicated when I was doing it by hand. For SPA-only I simply rendered an empty main app root element for every page, with no server data, and for SSR-only, I didn't include any JS file in the HTML. Now of course it's a bit more complicated in the Next architecture, but both are quite simple in theory.

Edit: I just realized that for development purposes, SSR-only can be achieved by just disabling JavaScript in the browser.

@eric-burel
Copy link
Contributor

Another use case I have for SSR disabling is education.
It would be very cool to be able to first learn Next without SSR, then activate SSR and show what it breaks, and then learn how to handle client-only code gracefully.

I strongly felt this need while trying to teach Next to data science students that are used to heavy client-only libraries like Chartjs, D3, leaflet etc. In the future I would probably favour Create React App for this reason, but I'd prefer keeping Next.

@johot
Copy link

johot commented Nov 10, 2020

I have created a web app that I host inside a React Native WebView. I love the developer experience of Next.js but in this case I have no use for SSR it just makes thing more complicated, gives me layout issues for non SSR supported hooks etc etc. In this case I want to use react router for the routing because of the support for nested routes that don't loose state and so on.

I would love an easy and official way of disabling SSR, right now I am following this guide by @tannerlinsley which is great:
https://gist.github.com/tannerlinsley/65ac1f0175d79d19762cf06650707830

I definately see a lot of use cases for a "SPA mode / no SSR mode".

Thank you for an awesome product @timneutkens !

@amirhbakan
Copy link

next export + next/router and a nginx that points for example / can work like SPA but it’s not the best solution, because next export generates many htmls and also if we accept multi htmls there is no way to point pages like product/[id] with nginx but it handled clientside with next/router.
I think next export + next/router could be a good solution for SPA mode with some features,
1- really generate one html or a solution for pointing dynamic routes pages with nginx.
2- handle 404 clientside in next/router with a flag.

@eric-burel
Copy link
Contributor

eric-burel commented Mar 12, 2022

next export + next/router and a nginx that points for example / can work like SPA but it’s not the best solution, because next export generates many htmls and also if we accept multi htmls there is no way to point pages like product/[id] with nginx but it handled clientside with next/router. I think next export + next/router could be a good solution for SPA mode with some features, 1- really generate one html or a solution for pointing dynamic routes pages with nginx. 2- handle 404 clientside in next/router with a flag.

That's the point of the proxy here. Last time I tested (a while ago), Next would produce a [id].html in fallback mode. You only get many HTML, eg one per post of your blog, if you don't use fallback. Your Nginx can point to this [id].html which would then be able to do client-side fetching to get the right content.
This is faster than an SPA because your code is split per page.

I agree that a pure SPA mode could be interesting as well, as it is the simplest way to export. However I've kinda dropped this idea a while ago, because I prefer the way Next uses the presence of the server intelligently.
If you really need an SPA, then Create React App might be a simpler alternative.

@amirhbakan
Copy link

amirhbakan commented Mar 13, 2022

next export + next/router and a nginx that points for example / can work like SPA but it’s not the best solution, because next export generates many htmls and also if we accept multi htmls there is no way to point pages like product/[id] with nginx but it handled clientside with next/router. I think next export + next/router could be a good solution for SPA mode with some features, 1- really generate one html or a solution for pointing dynamic routes pages with nginx. 2- handle 404 clientside in next/router with a flag.

That's the point of the proxy here. Last time I tested (a while ago), Next would produce a [id].html in fallback mode. You only get many HTML, eg one per post of your blog, if you don't use fallback. Your Nginx can point to this [id].html which would then be able to do client-side fetching to get the right content. This is faster than an SPA because your code is split per page.

I agree that a pure SPA mode could be interesting as well, as it is the simplest way to export. However I've kinda dropped this idea a while ago, because I prefer the way Next uses the presence of the server intelligently. If you really need an SPA, then Create React App might be a simpler alternative.

Thanks for the reply, but I need this because I have implemented the Dynamic rendering with NextJS, I want to have one codebase with an SSR build and a CSR build, my SSR side is just SSR, not SSG. we implemented it with some tricks, but I want a good solution for CSR build to really have a SPA. I think if these features implement, the Dynamic Rendering with NextJS is a robust technique for websites.

@habovh
Copy link

habovh commented Jun 8, 2022

For anyone looking for a simple and zero additional dependency solution, I suggest wrapping your app in a component that you can import using Next dynamic() import. Then you can check the router for a set query parameter, allowing you to easily debug issues on a one-off basis.

Something like this would "disable" SSR for any component below the <Main /> node when the URL contains the query string ?disable-ssr=1.

// _app.js
import dynamic from 'next/dynamic'

import MainSSR from '../components/main'

const MainNoSSR = dynamic(() => import('../components/main'), { ssr: false })

class MyApp extends App {
  render() {
    const { Component, router } = this.props
    const disableSSR = router.query['disable-ssr'] === '1'
    const Main = disableSSR ? MainNoSSR : MainSSR
    return (
      <>
        <Head>
          {...}
        </Head>
        <Main>
          <Component />
        </Main>
      </>
    )
  }
}

@verekia
Copy link

verekia commented Jun 8, 2022

@habovh This is really great. What's in MainSSR? Just something like const Main = ({ children }) => <>{children}</>?

@habovh
Copy link

habovh commented Jun 8, 2022

@verekia yup exactly. It's also handy to add content that must be present on every page —such as the cookie banner alongside the children.

Edit: just to be precise, I'm referring to the component exported in components/main that is being imported by both MainSSR and MainNoSSR using two different import methods.

@paulogaspar7
Copy link

New version of Ant Design's Pro-Components also not supporting SSR.
(Node complains with a "SyntaxError: Cannot use import statement outside a module".)

@remorses
Copy link
Contributor

I just created a Next.js plugin to disable SSR and remove all the React components from your server bundle.

This plugin will transform your pages to only return null in the server, causing dead code elimination to remove all the React components and libraries from your server output code. On the client, the pages will return null until mounted.

To use it simply add the skip ssr directive at the top of your pages:

// pages/index.js
'skip ssr'

export default function Home() {
    return <div>hello world</div>
}

Read more in the Elacca repository

@samcx
Copy link
Member

samcx commented Feb 21, 2024

Hi everyone!

Since this is a feature request, I will be moving this over to :nextjs: discussions. :loading:

@vercel vercel locked and limited conversation to collaborators Feb 21, 2024
@samcx samcx converted this issue into discussion #62352 Feb 21, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests