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
Support NextJS 13 /app directory server-side rendering? #6475
Comments
@ThomasAunvik Edit: add any library to the externals that requires react/client context |
Hey @Venipa, Your workaround does not work when the root layout is an Any idea why is this happening and how to fix this? |
probably due to app dir is still experimental and external packages not (yet) supported in async root layout (or in general async react components). |
Dear @Venipa, Thanks for your reply. Although you are most probably right about the
However, I might be wrong as in fact, the docs around the new next-js feature are not mature, hence, I might not be considering everything. |
I have created a WIP PR that makes react-bootstrap work with the appDir: #6532 it does require some polish before being final, any suggestions or assistance would be delightful - it can currently be considered a proof of concept |
I could not get your PR to work, is there anyone who is either working on this or making some progress with this issue. I would really like to test the new SSR functionalities of next 13 with bootstrap. |
Is there any ticket where we track the progress with regard to the the appDir, because this ticket is closed, but the issue seems to persist and the PR hasn't been completed yet and is missing some components. |
The issue with React-Bootstrap is that everything is considered a Client Component. Even trying to add a column with the Col component, React-Bootstrap pulls in code for potential modals. This requires you to add 'use client' to the top of any page using almost any React-Bootstrap component, which means it is no longer rendered on the server, but client side, which is probably not what you want. I have been using the class names for anything server side (such as instead of ), and for anything client side, that a visitor needs to interact with, such as a menu bar, I wrap it in a custom component that has 'use client' at the top.So for example, for my menu, I do the following: In app/layout.js import MainMenu from '../components/MainMenu.js'
export default function RootLayout({children}) {
return <html>
<head />
<body>
<MainMenu />
{children}
</body>
</html>
} in components/MainMenu.js 'use client'
import { Container, Nav, Navbar, NavDropdown, SSRProvider } from 'react-bootstrap'
export default function MainMenu() {
return <SSRProvider>
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link href="#home">Home</Nav.Link>
<Nav.Link href="#link">Link</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</SSRProvider>
} I'm not sure if the SSRProvider in the leaves instead of the root will cause me issues later, but for now, this is working. |
Indeed, most of the components are using the ThemeProvider, making this lib client-only (in its current form). |
Interesting, I wonder what the long term way forward is. It sounds like that approach could be a new project in itself as it sounds like react-bootstrap is just not compatible with this use case. |
I think I am running into this issue. We are beginning the process of converting a 100k line haml project into something modern; we picked nextJS for the SSR features and react-bootstrap for its well tested prebuilt components. We come to find out SSR doesn't seem to work with ANY pre built component libraries. Even next UI doesn't support it on the server: https://nextui.org/docs/guide/nextui-plus-nextjs. None appear to. But doesn't this end result effectively make SSR completely useless for the most common applications? If your writing a blog and you want to start rendering on the backend, you can't use the same components you were using before and there are no replacement components available even if your okay with the different styles and customizing; so you have to build custom primitives on the backside and probably wire everything with jquery instead of react (which SSR seems to handle fine and is basically doing the same thing as react-bootstrap as far as the browser is concerned). Fundamentally, I think this really is a NextJS issue, not an issue with react-bootstrap. I really don't know anything about the internals of nextJS, but I get the impression it has wrapped a lot of react functionality to work on both the server and the client by varying the rendering methods that are generated depending on where it is rendered. It seems they need to do the same for state, that maybe this isn't handled well enough on next SSR. For SSR generated states, I think it obviously wouldn't manage state on the backside, but I think the backside should be able to generate componentized dynamic JS that includes the state for the client to manage. Bottom line, for the first conversations we tried to make a frontend page with react-bootstrap button and it worked but we couldn't get it working with SSR, no prebuilt components work on SSR as far as I can tell, it only seems to handle uncontrolled components. So I think it only works with pure CSS styles and JS. Another reason I think this is NextJS's issue, no the lib manufacturers, is that the web based community just spent the last decade or so explicitly separating front and backend code for the advantages we thought we had, now nextJS is trying to shove them back together to retain some of the benefits. It uses JS/TS specifically to keep the language the same on the front and backend, and to avoid having to learn a traditional backend language I guess. But I can use react-bootstrap and PHP or other traditional backends without issue, I specify how its rendered and when. Even spring-boot, I hear, has a SSR method that does work with react-bootstrap as far as I can tell. So I'm not really sure where to go next... I guess we will use the modern next JS app folder and just separate backend frontend code in various data/view folders that can be hopefully be easily moved to be more isolated if nextJS SSR goes the way of the dinosaurs. I think you guys really do need to make this work with the most common unmodified component libraries. |
The root of the issue is that code exists in two forms in React:
Server-side code (any file that doesn’t return a JSX object)
Client-side code (any file that does return a JSX object), that is not pre-rendered in any way. It’s just packaged up and send to the client browser to deal with.
NextJS can only pre-render pages that return a JSX object whose javascript can be run at build time. To run any of the javascript client side, it either needs to be vanilla javascript (or jQuery) that can be put into a script tag, or a react file that starts with ‘use client’. So the trick is to build as much of the site with code that can run at build time. Anything that needs to run in the client’s browser needs to be broken out into a separate component. This way, NextJS can pre-render any page that returns a JSX object ahead of time, unless it has ‘use client’ as its first line. Since most all UI requires user interaction, it can’t be pre-rendered, so it needs to be put in its own file. Eventually, these libraries will put ‘use client’ themselves at the beginning of every component that needs to run in the browser, but until then, we have to make separate components ourselves.
… On Feb 28, 2023, at 9:42 AM, gunslingor ***@***.***> wrote:
I think I am running into this issue. We are beginning the process of converting a 100k line haml project into something modern; we picked nextJS for the SSR features and react-bootstrap for its well tested prebuilt components. We come to find out SSR doesn't seem to work with ANY pre built component libraries. Even next UI doesn't support it on the server: https://nextui.org/docs/guide/nextui-plus-nextjs. None appear to.
But doesn't this end result effectively make SSR completely useless for the most common applications? If your writing a blog and you want to start rendering on the backend, you can't use the same components you were using before and there are no replacement components available even if your okay with the different styles and customizing; so you have to build custom primitives on the backside and probably wire everything with jquery instead of react (which SSR seems to handle fine and is basically doing the same thing as react-bootstrap as far as the browser is concerned).
Fundamentally, I think this really is a NextJS issue, not an issue with react-bootstrap. I really don't know anything about the internals of nextJS, but I get the impression it has wrapped a lot of react functionality to work on both the server and the client by varying the rendering methods that are generated depending on where it is rendered. It seems they need to do the same for state, that maybe this isn't handled well enough on next SSR. For SSR generated states, I think it obviously wouldn't manage state on the backside, but I think the backside should be able to generate componentized dynamic JS that includes the state for the client to manage.
Bottom line, for the first conversations we tried to make a frontend page with react-bootstrap button and it worked but we couldn't get it working with SSR, no prebuilt components work on SSR as far as I can tell, it only seems to handle uncontrolled components. So I think it only works with pure CSS styles and JS.
Another reason I think this is NextJS's issue, no the lib manufacturers, is that the web based community just spent the last decade or so explicitly separating front and backend code for the advantages we thought we had, now nextJS is trying to shove them back together to retain some of the benefits. It uses JS/TS specifically to keep the language the same on the front and backend, and to avoid having to learn a traditional backend language I guess. But I can use react-bootstrap and PHP or other traditional backends without issue, I specify how its rendered and when. Even spring-boot, I hear, has a SSR method that does work with react-bootstrap as far as I can tell.
So I'm not really sure where to go next... I guess we will use the modern next JS app folder and just separate backend frontend code in various data/view folders that can be hopefully be easily moved to be more isolated if nextJS SSR goes the way of the dinosaurs.
I think you guys really do need to make this work with the most common unmodified component libraries.
—
Reply to this email directly, view it on GitHub <#6475 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AANMEAR2UIAZOA6DSWVKBZLWZYFE5ANCNFSM6AAAAAARPYV4DU>.
You are receiving this because you commented.
|
I am getting the same issue. I am using new app feature with react-bootstrap package |
So reading the above it seems like it might be a good idea to create an issue on the nextjs project itself. Or is there already an issue tracking this on the next project? |
I think this falls under the “it’s not a bug, it’s a feature”. It’s a decision they took to differentiate between code being run on the server and code being run in the client browser. Anything that changes the contents of a page due to client interaction or that stores data on the client side (useEffect, useContext, …) is run in the client browser and needs to be isolated in a client side component that starts with ‘use client’.
… On Mar 2, 2023, at 6:34 AM, DanielFortuyn ***@***.***> wrote:
The root of the issue is that code exists in two forms in React: Server-side code (any file that doesn’t return a JSX object) Client-side code (any file that does return a JSX object), that is not pre-rendered in any way. It’s just packaged up and send to the client browser to deal with. NextJS can only pre-render pages that return a JSX object whose javascript can be run at build time. To run any of the javascript client side, it either needs to be vanilla javascript (or jQuery) that can be put into a script tag, or a react file that starts with ‘use client’. So the trick is to build as much of the site with code that can run at build time. Anything that needs to run in the client’s browser needs to be broken out into a separate component. This way, NextJS can pre-render any page that returns a JSX object ahead of time, unless it has ‘use client’ as its first line. Since most all UI requires user interaction, it can’t be pre-rendered, so it needs to be put in its own file. Eventually, these libraries will put ‘use client’ themselves at the beginning of every component that needs to run in the browser, but until then, we have to make separate components ourselves.
… <x-msg://2/#>
On Feb 28, 2023, at 9:42 AM, gunslingor @.***> wrote: I think I am running into this issue. We are beginning the process of converting a 100k line haml project into something modern; we picked nextJS for the SSR features and react-bootstrap for its well tested prebuilt components. We come to find out SSR doesn't seem to work with ANY pre built component libraries. Even next UI doesn't support it on the server: https://nextui.org/docs/guide/nextui-plus-nextjs. None appear to. But doesn't this end result effectively make SSR completely useless for the most common applications? If your writing a blog and you want to start rendering on the backend, you can't use the same components you were using before and there are no replacement components available even if your okay with the different styles and customizing; so you have to build custom primitives on the backside and probably wire everything with jquery instead of react (which SSR seems to handle fine and is basically doing the same thing as react-bootstrap as far as the browser is concerned). Fundamentally, I think this really is a NextJS issue, not an issue with react-bootstrap. I really don't know anything about the internals of nextJS, but I get the impression it has wrapped a lot of react functionality to work on both the server and the client by varying the rendering methods that are generated depending on where it is rendered. It seems they need to do the same for state, that maybe this isn't handled well enough on next SSR. For SSR generated states, I think it obviously wouldn't manage state on the backside, but I think the backside should be able to generate componentized dynamic JS that includes the state for the client to manage. Bottom line, for the first conversations we tried to make a frontend page with react-bootstrap button and it worked but we couldn't get it working with SSR, no prebuilt components work on SSR as far as I can tell, it only seems to handle uncontrolled components. So I think it only works with pure CSS styles and JS. Another reason I think this is NextJS's issue, no the lib manufacturers, is that the web based community just spent the last decade or so explicitly separating front and backend code for the advantages we thought we had, now nextJS is trying to shove them back together to retain some of the benefits. It uses JS/TS specifically to keep the language the same on the front and backend, and to avoid having to learn a traditional backend language I guess. But I can use react-bootstrap and PHP or other traditional backends without issue, I specify how its rendered and when. Even spring-boot, I hear, has a SSR method that does work with react-bootstrap as far as I can tell. So I'm not really sure where to go next... I guess we will use the modern next JS app folder and just separate backend frontend code in various data/view folders that can be hopefully be easily moved to be more isolated if nextJS SSR goes the way of the dinosaurs. I think you guys really do need to make this work with the most common unmodified component libraries.
So reading the above it seems like it might be a good idea to create an issue on the nextjs project itself. Or is there already an issue tracking this on the next project?
—
Reply to this email directly, view it on GitHub <#6475 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AANMEATSYCDXSOIVE3N3R2DW2CAS5ANCNFSM6AAAAAARPYV4DU>.
You are receiving this because you commented.
|
@gunslingor react-bootstrap + Next.js 13 still support SSR, I think you are confusing React Server Components with Server Side Rendering. Anyway I agree with @rjantoine, React and Next.js are prioritizing static content with Next.js 13. If your project is interactive and does (form) mutations, the sacrifices made to support this direction may not be worth it. |
Just to keep you guys informed, my team did some successful tests with the reactstrap package. Apparently the migration wasn't too bad either. Just FYI. |
I was just trying to make a login form. Zero react-bootstrap components, or any other lib I tried for that matter, didn't work in ssr. It was a login page, never intended for complex form dynamics involving state, just a login page. I found the only way to SSR a login page is to rebuilt primitives like Button, Form, etc... restyling a style that already exists. If I have the option to use local, I should probably be given the option to "use view" so common libs, view layout and styles only, are still usable. I just can imagine a use case where a blog, the prime target for SSR, says okay let's rebuild all the primitives to support SSR because they don't work now and never will. |
Folks we aren't really going to update RB to work with server components until server components are stable and documented, otherwise it's a moving target we can't hit. RB components all continue to support normal react server side rendering. The entire react ecosystem depends on using create context for components so I can't imagine Next just doesn't work with most react components for sites, I assume you can tell it not to treat the components as RSCs and just do the old boring thing of rendering them on the server and hydrating |
I mean they're pretty stable and well-documented at the moment as far as I can tell...we've been using them for a while now and have no issues other than inability to use react-boostrap. As a matter of fact we have had no issues with any other frameworks in server components. I hope this is resolved soon--react-bootstrap is a lot better than alternatives like reactstrap for a lot of stuff. |
The main issue is that every inch of the react-bootstrap code uses context to store the theme. Context is done client side, not server side, and requires 'use client' in the new RSC paradigm. To be compatible with Next JS server components, things like themes that are likely to be a constant should be stored in an environment variable or config file, instead of in a context. The only things that should use state or context should be variables that can potentially change through user interaction. Since the react-bootstrap stream has indicated that they don't want to change anything until RSCs are stable, likely meaning when NextJS 13 is out of beta, the easiest solution is to put 'use client' at the top of the page.tsx file or to wrap any react-bootstrap code it in a ClientComponent wrapper.
|
Well not Page, as Page must be a server component, but it appears you can set a server component as the child of a client component (or pass it through as a prop). Docs: https://beta.nextjs.org/docs/rendering/server-and-client-components#importing-server-components-into-client-components |
Well, SSR not working with NextJS 13.3.0! |
works for me...we're now using the nested component strat and it's working just fine. Would be cool to do full ssr with react bootstrap but letting the clients handle the bulk of the ui is working out alright. |
Kinda completely defeats the purpose and performance improvements that React Server Components are supposed to bring. Anybody know if |
I’ve been using vanilla bootstrap in any server side pages and have only been using the libraries in client components that need interactivity.On May 10, 2023, at 1:18 PM, starlight-akouri ***@***.***> wrote:
Kinda completely defeats the purpose and performance improvements that React Server Components are supposed to bring. Anybody know if react-bootstrap is going to plan on implementing the Context differently in the future? Or should I try to migrate to something else for a new project?
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: ***@***.***>
|
Folks, PRs welcome. If it's clear to you that RSC are awesome and supporting them is easy and straightforward, please send the PR. We would really love that, very seriously. Otherwise, please wait until we have time to devote to figuring out how to add support in a way that supports RBs diverse and expansive user base. Going to lock the convo now since it's mostly folks +1-ing which isn't super helpful. |
@WalterOkumu and others, "use client" components are still SSR'd and produce HTML that is sent to the client. They work just like SSR always has, and react bootstrap components are all SSR compatible. You don't need the new server components to get SEO. The new RSC stuff isn't a SEO solution it's a js bundle reduction improvement. Folks are conflating features or misunderstanding what RSC is compared to "normal" SSR. |
@jquense re: https://nextjs.org/docs/getting-started/react-essentials#third-party-packages Would the first and easiest thing be to just add |
yes we can do that, ideally as part of the build step so we don't have to remember to do it for every new file |
Hi @jquense, |
If I understand correctly, the simplest thing initially would be to put a single Later, optimisations could be made to push Note that react have
|
This is all true, but I would not say that bundle reduction is the main benefit that React Server Components provide. Rather, the main reason to use Server Components is that they make it possible to build components that can run code that belongs on the server side, such as authenticated API requests, database requests, etc. Considering the “fetch data where it's used” recommendation – https://nextjs.org/docs/app/building-your-application/data-fetching – it is desirable that client components are only required where they are strictly necessary (because they need to access browser events or similar), as close to the leaf nodes of the page structure as possible. |
This solution is causing issues within the next modules.
More discussions about this issue. Seems to me that setting An approach that makes more sense to me is to add |
I think it might be helpful to share my temporary solution—wrap react-bootstrap components in a separate file with the 'use client'
import { PropsWithChildren, ComponentProps } from "react"
import { Button, Col, Container, Nav, Row } from "react-bootstrap"
export function withClient<PropsType extends PropsWithChildren>(
ComponentToBeWrapped: React.ComponentType<PropsType>
): React.FC<PropsType> {
function WrappedComponent({children, ...otherProps}: PropsType) {
return <ComponentToBeWrapped {...otherProps as PropsType}>
{children}
</ComponentToBeWrapped>
}
return WrappedComponent
}
export const ClientContainer = withClient<ComponentProps<typeof Container>>(Container);
export const ClientCol = withClient<ComponentProps<typeof Col>>(Col);
export const ClientRow = withClient<ComponentProps<typeof Row>>(Row);
export const ClientNav = withClient<ComponentProps<typeof Nav>>(Nav);
export const ClientNavLink = withClient<ComponentProps<typeof Nav.Link>>(Nav.Link);
export const ClientButton = withClient<ComponentProps<typeof Button>>(Button);
I really hope this issue will be resolved from the developer's side, otherwise I won't use react-bootstrap with Next.js applications in the future. |
@alicia-lyu I have a similar workaround, but I think it can be simpler, like: // client-react-bootstrap.ts
"use client";
export { Col, Container, Offcanvas, Row } from "react-bootstrap"; I then make sure to import any |
I just released v2.9.0-beta.1 that should support RSC as best as we could right now. There is a known issue where you can't use the dot notation for components such as This is tracked here: #6669 Please give it a try and let me know if there are any issues. |
Yes it works, except that for dot notation components like export const NavLink = Nav.Link; It's good to know there is a simpler solution. Thank you! |
Looks great. I will reply in your original thread for future issues. |
I think this workaround only works for non-interactive components Here's what I get when I passed an |
@IamGideonIdoko I think that's expected. The same would occur for a basic |
So probably the best solution for now is to stick with Pages router instead of App router when creating a new app? |
@marceloverdijk Depends if you then plan to migrate from Pages router to App router in the future. If so, my opinion from experience would be to start with App router and just use a simple workaround for this |
Sorry for the delay. I promoted the beta to stable since it appeared to be mostly working. Same caveats apply: #6669 |
Thx for your feedback @cduff . But I wonder does that impact my generated code when using a SSG ? As much as possible should be generated when exporting and not on the client. @kyletsang Indeed when upgrading to |
👍
I believe #6475 (comment) may be relevant.
See #6475 (comment). |
Hi there, @kyletsang . Next.js components are server-side components by default.(https://nextjs.org/docs/messages/context-in-server-component) This problem cannot be solved quickly at present. Developers using React will face a lot of pain. The code they write will be terrible, bad and inelegant. Developers will be very hesitant and usually will not easily decide to use react-bootstrap, but will Looking for other frameworks, Next.js is currently the mainstream of front-end development, |
Prerequisites
Describe the bug
React-Bootstrap tries to use React.createContext on server-side?
Expected behavior
To render out a component
To Reproduce
npx create-next-app@latest --ts
npm run dev
Reproducible Example
https://codesandbox.io/p/sandbox/bold-neco-p5zv6j
Screenshots
No response
What operating system(s) are you seeing the problem on?
Windows
What browser(s) are you seeing the problem on?
Firefox
What version of React-Bootstrap are you using?
2.5.0
What version of Bootstrap are you using?
5.2.2
Additional context
vercel/next.js#41929
The text was updated successfully, but these errors were encountered: