Repository navigation
Private pages in Next, even when you don't have a server #49 #14531
Replies: 3 comments 3 replies
|
To be very concrete, I do not expect to get this error during The pages should simply not be rendered, but be kept available in the app client-side. |
3rd attempt, working okI think I've figured out, see code here Basically:
Now, all tests are passing: SSR, client side, shallow routing, and static mode. What I did not test at this point, is Apollo data fetching. Cases I needed to handle
I think the client side rendering after redirect/in static mode is inelegant. We use a |
|
I made it an HOC available here, I think the ssr/static part is ok but I'd like to have feedback on the client-side redirections, which are triggered when running the app after I also lack an elegant pattern to handle the case where you use a hook to check auth, like Apollo |
Uh oh!
There was an error while loading. Please reload this page.
Crosspost from VulcanJS/vulcan-next#49, where we provide the full code
Goal
Easy, intuitive, way of creating private pages visible only by logged in users.
Should work with and without SSR.
Should also work in client-only context, like any other "JAMstack"-friendly framework.
Previous art
Question "How to redirect in getStaticProps" in Next repo. This is the most insightful ressource on the question, as it raises the broader question of redirect in a static page. The page being private is a special case of this, where you not only want the user to be redirected if not logged in, but you also want the static version of the page to never exist in the first place.
Stack overflow question
Example that works in dynamic mode, but does not talk at all about static render
My unanswered question in spectrum regarding redirection Dead link...
RFC about custom route, don't seem to adresse the issue
Hosting on github pages => leads to a dead wiki link
What about Gatsby? The key difference between Gatsby and Next is the Next's ability to do dynamic server side rendering, which is necessary to create real "private" pages with SSR. In Gatsby, private pages are client-side only. That defeats the purpose of dynamic SSR.
What we need
Private pages only make sense either client-side, or during dynamic server-render, because they depend on whether the user is logged in or not.
Static render happens on your dev machine, once, like the application build itself, so it does not know the end user. Private page of a statically rendered Next app should be rendered client-side only.
First attempt, with
getInitialPropsin custom _appIntuitively, if you are used to react-router or alike, you'll want to setup a global redirection at the top level, so basically adding auth checking and redirection in
_appgetInitialPropsTL;DR: this is wrong. This is intuitively what you'll do when used to React router or alike. You'll define an array of public routes, and let the user pass when the route match. That's wrong. You'll redirect to the login page if the user is trying to open a private route while not being connected. Wrong wrong wrong.
In Next, the router is the page. Everything must happen at the page level. Defining the layout, defining redirections, checking auth, etc., etc.
I've never met yet a page with only private pages, if only the login page.
My takeaways:
Router.pushto redirect.appContext.ctx.resis available both during STATIC server-render and DYNAMIC server-render.You need to check forres.writeHeadto be available if you want to redirect during server render._apprender based on props status computed during getInitialProps. I've had a weird behaviour breaking apollo SSR of private pages. Basically the app props were not directly enhanced withcurrentUser, computed during this call. So the Apollo queries were not collected as expected duringgetDataFromTree, resulting in an app in loading state.Code looks like this and you should not do that because this is wrong:
Second attempt, with getServerSideProps and getStaticProps, in the page
Issues I struggle to solve
I can't tell from the doc and all articles and answer what's the best course of actions to create a private page in Next.
As far as I understand,
next exportis the only way to have an application that do not rely on the server. Something I could host on GitHub pages.From the doc:
Agree with that. However, it's not because a page cannot be prerendered, that you don't want the whole app not to be statically exported.
next buildWON'T create such an app, as far as I understand. Or at least, I found no doc about this.If you define a page with
getServerSideProps, which you need to in order to have server-side redirect, Next considers that you opt out from static export. This feels wrong, I could still want to have a simple client-side redirect in scenarios whereAll reactions