-
Notifications
You must be signed in to change notification settings - Fork 30
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
Private pages in Next, even when you don't have a server #49
Comments
I see you linked my post about private routes in nextjs (with no static mode examples). The static mode examples should be basically the same thing as a traditional ReactJS (all client side) application. If there is anything I can do to help out, or if you want to bounce any ideas around, I’m here! |
@jasonraimondi I think I've figured it out. If you have some spare time, checking this example component and this comment would be awesome. I think it works and covers all uses cases, but I'd love a double check. It's not really like a normal app, because you have to hack Next a bit. First you can't use Edit: ok actually when you open the page in static mode, it still gives you a glimpse of the private page instead of rendering nothing. But we progress. |
I'll make this a reusable page wrapper, I think that's doable to abstract everything into an HOC + a getInitialProps enhancer. |
From what I can see, it seems like you do have all the cases covered:
It seems that adding the additional use cases in addition to my "server only" approach does add a lot of complexity. It would definitely be worth abstracting yours into a HOC and just wrapping any private page in that component. This file would just need a bit of refactoring to be that HOC. This is my more simple example of the HOC that lacks support for the use cases of |
I've made it an HOC this morning, see withPrivateAccess here. It still works for all scenarios. I think the client-side render is still kinda clumsy and inelegant, I have hard time figuring out right pattern. You might want to support:
However I am not sure how I could use hooks with this HOC. In Apollo, the alternative is to get and call the client-side apollo client manually, without a hook, in the |
See #71 |
To sum it up, SSR, and thus dynamic server side redirections for private pages, leads to a lot of complexity. Instead, we should consider pages as always public, and find another pattern to secure them dynamically (eg a reverse proxy or an upfront server). |
Edit: current progress:
next export
🎉.useCurrentUser
like we do in Vulcan, based on Apollo'suseQuery
)localStorage
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
Vulcan Access Component
Discussion I've just opened on Next
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
Issue with admin routes
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
getInitialProps
in 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
_app
getInitialProps
TL;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.push
to redirect.appContext.ctx.res
is available both during STATIC server-render and DYNAMIC server-render.You need to check forres.writeHead
to be available if you want to redirect during server render._app
render 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 export
is 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 build
WON'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 whereThe text was updated successfully, but these errors were encountered: