You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm currently building an application that is based on this repo with two applications in a monorepo where users can create sites on a separate dashboard app.
When a user updates e.g. his theme data I need to purge the cache for all pages of his subdomain or domain.
My current implementation looks like this
I use radix themes as a base color provider for tailwind. Radix Ui uses a Theme Provider that adds html attributes to a div that wrapps the whole application that looks like this:
Here's my layout that feeds the values from the database into the Theme provider:
importtype{ReactNode}from"react";importtype{Metadata}from"next";import{notFound,redirect}from"next/navigation";import{Theme}from"@radix-ui/themes";import{getPublicSiteData}from"@acme/api/src/fetchers/site";import{CompanyThemeSchema}from"@acme/api/src/schemas/custom/theme";import{prisma}from"@acme/db/src/db";import{Navbar}from"~/components/nav/navbar";import{Footer}from"~/components/sections/Footer";/////////////////////////////////////////////////// GENERATE STATIC PARAMS/////////////////////////////////////////////////exportasyncfunctiongenerateStaticParams(){constallSites=awaitprisma.site.findMany({select: {subdomain: true,customDomain: true,},});constallPaths=allSites.flatMap(({ subdomain, customDomain })=>[subdomain&&{domain: `${subdomain}.${process.env.NEXT_RFK_ONLINE_ROOT_DOMAIN}`,},customDomain&&{domain: customDomain,},]).filter((value): value is RootParamsType=>Boolean((valueasRootParamsType)?.domain),);returnallPaths;}exportinterfaceRootParamsType{domain: string;}/////////////////////////////////////////////////// GENERATE METADATA/////////////////////////////////////////////////exportasyncfunctiongenerateMetadata({
params,}: {params: RootParamsType;}): Promise<Metadata|null>{constdomain=decodeURIComponent(params.domain);const{ data }=awaitgetPublicSiteData(domain);if(!data){returnnull;}const{name: title,
description,
image,
logo,}=dataas{name: string;description: string;image: string;logo: string;};return{
title,
description,openGraph: {
title,
description,images: [image],},twitter: {card: "summary_large_image",
title,
description,images: [image],creator: "@vercel",},icons: [logo],metadataBase: newURL(`https://${domain}`),// Optional: Set canonical URL to custom domain if it exists// ...(params.domain.endsWith(`.${process.env.NEXT_RFK_ONLINE_ROOT_DOMAIN}`) &&// data.customDomain && {// alternates: {// canonical: `https://${data.customDomain}`,// },// }),};}/////////////////////////////////////////////////// LAYOUT/////////////////////////////////////////////////exportdefaultasyncfunctionSiteLayout({
params,
children,}: {params: RootParamsType;children: ReactNode;}){constdomain=decodeURIComponent(params.domain);const{ data, error }=awaitgetPublicSiteData(domain);if(!data||error){notFound();}// Optional: Redirect to custom domain if it existsif(domain.endsWith(`.${process.env.NEXT_RFK_ONLINE_ROOT_DOMAIN}`)&&data.customDomain&&process.env.REDIRECT_TO_CUSTOM_DOMAIN_IF_EXISTS==="true"){returnredirect(`https://${data.customDomain}`);}consttheme=CompanyThemeSchema.parse(data.theme);return(<Theme{...theme}><Navbar/><mainclassName="min-h-screen">{children}</main><Footeremail={data.company?.email}phoneNumber={data.company?.phoneNumber}mobilePhone={data.company?.mobilePhone}/></Theme>);}
The fetcher looks like this:
///////////////////////////////////////////////////////// GET PUBLIC SITE DATA///////////////////////////////////////////////////////exportasyncfunctiongetPublicSiteData(domain: string){returnawaitunstable_cache(async()=>{returnserverApi(null,async(api)=>api.site.findPublicSite(domain));},[`${domain}-metadata`],{tags: [`${domain}-metadata`]},)();}exporttypeGetSiteDataReturnType=RouterOutputs["site"]["findPublicSite"];
the revalidate site route handler looks like this:
import{revalidatePath,revalidateTag}from"next/cache";importtype{NextRequest}from"next/server";import{NextResponse}from"next/server";import{z}from"zod";///////////////////////////////////////////// TYPES///////////////////////////////////////////exporttypeRevalidateThemeInputInputType=z.infer<typeofRevalidateThemeInputSchema>;exporttypeRevalidateThemeRequestType=z.infer<typeofRevalidateThemeRequestSchema>;///////////////////////////////////////////// SCHEMAS///////////////////////////////////////////exportconstRevalidateThemeInputSchema=z.object({domain: z.string(),});exportconstRevalidateThemeRequestSchema=RevalidateThemeInputSchema.extend({secret: z.literal(process.env.REVALIDATION_SECRET),});constPATHS_TO_REVALIDATE=["/","/wissenswertes","/wissenswertes/[slug]","/kontakt","/impressum","/cookies","/datenschutz","/beruf",];//////////////////////////////////////////////// ROUTE HANDLERS//////////////////////////////////////////////exportasyncfunctionPOST(req: NextRequest){constbody=(awaitreq.json())asunknown;constparsedRequest=RevalidateThemeRequestSchema.safeParse(body);if(!parsedRequest.success){console.error(parsedRequest.error);returnNextResponse.json({status: 400,body: {message: "Invalid request body",errors: parsedRequest.error,},});}const{ domain }=parsedRequest.data;// Revalidate metadata so the site data is re-fetchedconsttag=`${domain}-metadata`;revalidateTag(tag);console.log("Revalidating tags: ",tag);// Revalidate all paths so each page gets the new theme dataPATHS_TO_REVALIDATE.forEach((path)=>{console.log("Revalidating paths: ",`${domain}${path}`);revalidatePath(`/${domain}${path}`,"layout");revalidatePath(`/${domain}${path}`,"page");});returnNextResponse.json({status: 200,body: {message: "OK",},});}
which is called with this fetcher in every endpoint that changes theme data:
Everything is working so far except that the theme data is not updated on every page of the given domain when revalidation is triggered.
For example on https://mydomain the theme data looks like this after reloading the page:
<divdata-accent-color="green"
...
/>
and on other pages like https://mydomain/subpage the theme data still has the old color:
<divdata-accent-color="tomato"
...
/>
So how would I go about this?
The main page is updated correctly but all other paths keep having the old theme data. I assume this si because the theme is added in the root layout and therefore only the page in the same directory is purged from the cache and rebuilt with the new site data.
It also seems that the revalidatePath(/${domain}${path}, "layout"); is not doing anything. I assume this is because I use an absolute url paht like my-subdomain.at-my-domain.at/mypath and not the file system path as mentioned in the docs.
I also tried using the dynamic segment like [domain]/mypath but also no luck.
Any Ideas how this could be fixed so the theme is updated on all subpages as well?
The text was updated successfully, but these errors were encountered:
I'm currently building an application that is based on this repo with two applications in a monorepo where users can create sites on a separate dashboard app.
When a user updates e.g. his theme data I need to purge the cache for all pages of his subdomain or domain.
My current implementation looks like this
I use radix themes as a base color provider for tailwind. Radix Ui uses a Theme Provider that adds html attributes to a div that wrapps the whole application that looks like this:
Here's my layout that feeds the values from the database into the Theme provider:
The fetcher looks like this:
Which calls a trpc endpoint server side
the revalidate site route handler looks like this:
which is called with this fetcher in every endpoint that changes theme data:
Everything is working so far except that the theme data is not updated on every page of the given domain when revalidation is triggered.
For example on
https://mydomain
the theme data looks like this after reloading the page:and on other pages like
https://mydomain/subpage
the theme data still has the old color:So how would I go about this?
The main page is updated correctly but all other paths keep having the old theme data. I assume this si because the theme is added in the root layout and therefore only the page in the same directory is purged from the cache and rebuilt with the new site data.
It also seems that the
revalidatePath(
/${domain}${path}, "layout");
is not doing anything. I assume this is because I use an absolute url paht likemy-subdomain.at-my-domain.at/mypath
and not the file system path as mentioned in the docs.I also tried using the dynamic segment like
[domain]/mypath
but also no luck.Any Ideas how this could be fixed so the theme is updated on all subpages as well?
The text was updated successfully, but these errors were encountered: