Comments (8)
Thanks @GabeDahl for digging into this and reporting!
@dalkommatt and @chriscarrollsmith I remember y'all doing this as part of the awesome Next.js 14 rework. Do you happen to have any guidance on this?
from nextjs-subscription-payments.
@thorwebdev @GabeDahl I have an open PR with a full rework of the navbar:
I can't speak to the time to first byte or the rendering sequence, because I haven't done any benchmarking on it. But I think it may resolve the problem? Give it a look.
from nextjs-subscription-payments.
@chriscarrollsmith I cloned your PR and removed all the async stuff from the home page (pricing page). So the root page.tsx is just:
export default function PricingPage() {
return (
<div>hello world</div>
);
}
This should result in a static, pre-rendered page during the build process.
However:
You can see that all routes are still dynamic, and thus rendered on-demand at request time. This means that a website visitor will have to wait for server to cold-start & render the route instead of just serving the static content. (hence, a long time to first byte)
If you remove the navbar, static generation and pre-rendering work as expected.
So it appears that including a server component in the root layout prevents static rendering.
from nextjs-subscription-payments.
I ended up replacing the server-rendered component with a client component (I get the session, but that can be easily swapped for user):
'use client'
import { createClient } from '../../../utils/supabase/client';
...
export default function Header() {
const path = usePathname();
const [session, setSession] = useState<Session | null>();
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session);
});
const {
data: { subscription }
} = supabase.auth.onAuthStateChange((_event, session) => {
setSession(session);
});
return () => subscription.unsubscribe();
}, [path]);
return (
...
It's not very elegant, but that's how I worked around some wonky issues with Next's root layout and direct child components (in other words, child components that are not part of any page, just the root layout)
from nextjs-subscription-payments.
Hi @GabeDahl, I'm interested to hear how you would rework it. The whole point of a navbar is that it's present on every page. I'm really hoping partial pre-rendering goes stable in Next.js 15, as it should solve this issue automatically if the <Navbar>
component is wrapped in <Suspense>
. Until then the only other alternative I'm aware of would be to create a sign in/sign out client component wrapped in <Suspense>
and fetch the user client side, but you may run into issues there as well because supabase/ssr's createBrowserClient
is not able to recognize a server-side sign in without the page being refocused or having a hard refresh.
from nextjs-subscription-payments.
@dalkommatt You're right. SSR's browser client doesn't recognize server-side auth state changes. That's why I hacked together that ugly useEffect
that fires whenever the pathname changes or whenever supabase.auth.onAuthStateChange
fires (to catch client-side auth updates).
My "fix" assumes that any server-side auth updates are accompanied with navigation/redirects. This repo already does that with the handleRequest
and SignOut
from /utils/auth-helpers/...
, but that's a dangerous assumption to apply generally.
Partial pre-rendering is definitely the ideal solution. So I see three options:
- Keep the current dynamic Navbar and endure a really slow TTFB.
- Use my workaround which [dangerously] assumes devs will navigate following any server-side auth updates.
- Use the experimental partial pre-rendering
It's honestly a tough call. I'll personally opt for 2 or 3 in my projects, but that might not be ideal for a template/repo like this.
from nextjs-subscription-payments.
Interesting, @GabeDahl. I appreciate your work on this. I agree that #2 or #3 is the way to go. Thanks also for the sample code; I will have to play around with that a bit. In our work on this repo, we were trying to keep auth management fully server-side for security purposes. But may have wedded ourselves a little too rigidly to that paradigm, especially considering that full SSR support in Next.js and Supabase was (and still is) still relatively new.
from nextjs-subscription-payments.
This might be very pointless and not a good solution. I do not have a navbar in my layout since I am using the index page as a landing page and I have a Dashboard route that holds a layout and in there I have my main navbar that renders if the user is logged in, if not , users are redirected to the landing page.
from nextjs-subscription-payments.
Related Issues (20)
- How to set up free trial payment option? HOT 4
- UserName is not Updating the users table, instead the Main Auth
- Vercel Deploy button - Infinite Completing Installation...
- Deprecating `auth-helpers` HOT 2
- 'Lifetime' feature on Pricing component does not work
- Magic link sign in doesn't actually sign in
- Are multiple calls to the same Supabase operation cached across pages and components? HOT 8
- Turning this into a shadCn template HOT 2
- Add --silent flag to piped npx commands
- Question - Any reason for OAuth being only available on signin's and not signups? HOT 2
- Issue with payment plans showing up
- Deploy error HOT 1
- Some issues with initial deploy, but after making my own workarounds, everything is fine.
- Persistent warning in console: "Using the user object as returned from supabase.auth.getSession()... could be insecure"
- Error: React Hook "useRouter" is called conditionally. React Hooks must be called in the exact same order in every component render.
- Is tanstack query a meaningful edition for this template.
- [Stripe Webhook] Not update latest status of the subscription object
- await checkoutWithStripe(price, currentPath) not working on localhost
- Webhook for production mode HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nextjs-subscription-payments.