Help me fix and understand cache component issues in my code
Answered
Golden paper wasp posted this in #help-forum
Golden paper waspOP
I have enabled the cache component and I am starting to feel the issues while implementing it
Error
I am just showing the user name and logout buttons.
What is the cache component way of handling this??
The solution is suspense but I don't want to use it as it will defeat the purpose of SSR. I don't want to use skeleton for navbar or the authenticate d part
Help me understand if I am understanding it wrong.
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Navbar from "@/components/navbar";
import { ToasterTopLoader } from "@/components/toaster-toploader";
import { checkAuthentication } from "@/features/auth/utils/check-auth";
import { Suspense } from "react";
import { NavbarAuth } from "@/components/navbar-auth";
const inter = Inter({
variable: "--font-inter",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Snippets",
description: "Snippets",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const authenticationData = await checkAuthentication();
return (
<html lang="en">
<body className={`${inter.className} antialiased`}>
<ToasterTopLoader />
<Navbar currentUser={authenticationData.user} />
<main className="max-w-7xl mx-auto px-4">{children}</main>
</body>
</html>
);
}Error
Data that blocks navigation was accessed outside of <Suspense>
This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation.
To fix this, you can either:
Provide a fallback UI using <Suspense> around...I am just showing the user name and logout buttons.
What is the cache component way of handling this??
The solution is suspense but I don't want to use it as it will defeat the purpose of SSR. I don't want to use skeleton for navbar or the authenticate d part
Help me understand if I am understanding it wrong.
Answered by Cinnamon Teal
Wrapping the components that does async work won't affect SSR. The fallback UI will be included in the initial HTML that gets sent to the client.
You can move the auth inside the navbar and wrap the whole Navbar in suspense.
Or if majority of the Navbar can be rendered without the auth check, then isolate the part within the navbar that needs the auth check and only wrap that in suspense. So the rest of the Navbar content is present in the initial render.
With cacheComponents, you have 2 options with async data.
1. You wrap the component that does async work in Suspense, so that a fallback UI is sent in the initial render while the async work happens.
2. You do the async work at built time and cache it using
In this case you can't cache the user profile, as it depends on request time data. So your option will be isolating the parts that needs to be rendered at request time.
You can move the auth inside the navbar and wrap the whole Navbar in suspense.
Or if majority of the Navbar can be rendered without the auth check, then isolate the part within the navbar that needs the auth check and only wrap that in suspense. So the rest of the Navbar content is present in the initial render.
function Navbar() {
return (
<header>
<nav>all your nav elements</nav>
<Suspense fallback={<SomeLoadingSkeleton />}>
<UserProfile />
</Suspense>
</header>
}
function async UserProfile() {
const user = await checkAuthentication()
return (
// ...render something with the user data
)
}With cacheComponents, you have 2 options with async data.
1. You wrap the component that does async work in Suspense, so that a fallback UI is sent in the initial render while the async work happens.
2. You do the async work at built time and cache it using
use cache.In this case you can't cache the user profile, as it depends on request time data. So your option will be isolating the parts that needs to be rendered at request time.
4 Replies
Cinnamon Teal
Wrapping the components that does async work won't affect SSR. The fallback UI will be included in the initial HTML that gets sent to the client.
You can move the auth inside the navbar and wrap the whole Navbar in suspense.
Or if majority of the Navbar can be rendered without the auth check, then isolate the part within the navbar that needs the auth check and only wrap that in suspense. So the rest of the Navbar content is present in the initial render.
With cacheComponents, you have 2 options with async data.
1. You wrap the component that does async work in Suspense, so that a fallback UI is sent in the initial render while the async work happens.
2. You do the async work at built time and cache it using
In this case you can't cache the user profile, as it depends on request time data. So your option will be isolating the parts that needs to be rendered at request time.
You can move the auth inside the navbar and wrap the whole Navbar in suspense.
Or if majority of the Navbar can be rendered without the auth check, then isolate the part within the navbar that needs the auth check and only wrap that in suspense. So the rest of the Navbar content is present in the initial render.
function Navbar() {
return (
<header>
<nav>all your nav elements</nav>
<Suspense fallback={<SomeLoadingSkeleton />}>
<UserProfile />
</Suspense>
</header>
}
function async UserProfile() {
const user = await checkAuthentication()
return (
// ...render something with the user data
)
}With cacheComponents, you have 2 options with async data.
1. You wrap the component that does async work in Suspense, so that a fallback UI is sent in the initial render while the async work happens.
2. You do the async work at built time and cache it using
use cache.In this case you can't cache the user profile, as it depends on request time data. So your option will be isolating the parts that needs to be rendered at request time.
Answer
Golden paper waspOP
Okay
Wouldn't that cause layout shift or sudden movement or flash of content? Like this is one of the reason I am doing SSR else this same thing was in SPA
Why are we going back to SPA style thing??
I want to cache things selectively.
Wouldn't that cause layout shift or sudden movement or flash of content? Like this is one of the reason I am doing SSR else this same thing was in SPA
Why are we going back to SPA style thing??
I want to cache things selectively.
Cinnamon Teal
Wouldn't that cause layout shift or sudden movement or flash of content?Not really, you could create a skeleton that is a similar size of the button and the user avatar (or whatever the UI you render for user data part in the Navbar). So when it gets switched to the actual data there won't be much a of a size difference.
I want to cache things selectively.You can with
use cache.https://nextjs.org/docs/app/getting-started/cache-components
https://nextjs.org/docs/app/api-reference/directives/use-cache
It's just that the user data is not something you can cache as it depends on each request.
Golden paper waspOP
Thanks for the response but I somewhat feel different me to than what I have thought of SSR.