import React from 'react';
import PricingPlansMain from '@/components/pages/PricingPlansPage';
import { getMeAction } from '@/server/auth-actions';
import { getAgentPricingPlansAction } from '@/server/payment-actions';
import PageLayout from '@/components/ui/PageLayout';
import UserCtxLayoutProvider from '@/components/ui/UserCtxLayoutProvider';
import styles from '@/components/pages/PricingPlansPage/styles.module.css';
export default async function PricingPlansPage() {
const userData = (await getMeAction())?.success;
const plans = await getAgentPricingPlansAction();
return (
<UserCtxLayoutProvider userData={userData}>
<PageLayout
headerClass={styles.header}
headerTheme='light'
logoConfig={{ theme: 'black', variant: 'full' }}
headerVersion='full'
footerTheme='default'
>
<PricingPlansMain plans={plans} />
</PageLayout>
</UserCtxLayoutProvider>
);
}
export const getMeAction = async () => {
try {
const res = await fetch(`${process.env.BACKEND_BASE}/users/me`, {
cache: 'no-store',
headers: { ...getAuthorizationHeader() },
next: { tags: [getCacheKey('userData')] },
});
if (!res.ok) {
throw new Error('server_error');
}
const { data } = await res.json();
return { success: data as UserType };
} catch (err) {
return { error: 'server_error' };
}
};
export async function getAgentPricingPlansAction() {
try {
const res: Response = await fetch(
`${process.env.BACKEND_BASE}/payments/plans/prices`,
{
method: REQUEST_METHODS.GET,
headers: {
...getNodeRequiredRequestHeaders(),
...getAuthorizationHeader(),
},
}
);
if (!res.ok) {
throw new Error('unexpected error');
}
const data: PricingPlansActionResponseType = await res.json();
return data;
} catch (err: any) {
throw new Error(err.message as string);
}
}
I'm using the App Router in my Next.js project and running into the following error when trying to pre-render a page:
Error: Dynamic server usage: Page couldn't be rendered statically because it used `headers`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error
at o (D:\upwork\movein\new frontend\muuve-frontend\.next\server\app\(website)\pricing-plans\page.js:1:13234)
at o (D:\upwork\movein\new frontend\muuve-frontend\.next\server\app\(website)\pricing-plans\page.js:1:12434)
Error occurred prerendering page "/pricing-plans". Read more: https://nextjs.org/docs/messages/prerender-error
The error occurs when I call a function to fetch pricing plans from the server. However, if I comment out the part of the code that fetches the pricing plans, everything works fine.
I have solved this error by using this workarround:
isDynamicServerError
. i have copied the solution from this post :
Dynamic server usage: Page couldn't be rendered statically because it used `nextUrl.searchParams` in Next.js version 14
export const getMeAction = async () => {
try {
const res = await fetch(`${process.env.BACKEND_BASE}/users/me`, {
cache: 'no-store',
headers: { ...getAuthorizationHeader() },
next: { tags: [getCacheKey('userData')] },
});
if (!res.ok) {
throw new Error('server_error');
}
const { data } = await res.json();
return { success: data as UserType };
} catch (err) {
/** NOTE
* This is a workaround
* For the issue of next.js not being able to render the page statically
* This issue arises in the pricing page
* https://stackoverflow.com/questions/78010331/dynamic-server-usage-page-couldnt-be-rendered-statically-because-it-used-next
**/
if (isDynamicServerError(err)) {
throw err;
}
return { error: 'server_error' };
}
};
But again my question why this error is aresing only in this page becase i have other pages too where i am calling the same server action and i am not getting this error there
import DashboardProperitesMain from '@/components/pages/DashboardProperitesPage';
import UserCtxLayoutProvider from '@/components/ui/UserCtxLayoutProvider';
import { PropertiesStatusFilterEnum } from '@/config';
import { Roles } from '@/schemas';
import { getMeAction } from '@/server/auth-actions';
import { redirectBaseOnRole } from '@/server/helper';
import { UserType } from '@/types';
export default async function DashboardHome({
searchParams,
}: {
searchParams?: {
page?: string;
status?: PropertiesStatusFilterEnum;
};
}) {
const currentPage = Number(searchParams?.page) || 1;
const userData = (await getMeAction())?.success;
redirectBaseOnRole(userData, [
Roles.ADMIN,
Roles.LANDLORD,
Roles.SUB_USER,
Roles.AGENT,
]);
return (
<UserCtxLayoutProvider userData={userData}>
<DashboardProperitesMain
userData={userData as UserType}
currentPage={currentPage}
status={searchParams?.status}
/>
</UserCtxLayoutProvider>
);
}
Main:
import React from 'react';
import { Suspense } from 'react';
import TableWrapper from '@/components/pages/DashboardProperitesPage/TableWrapper';
import Header from '@/components/pages/DashboardProperitesPage/Header';
import { DashboardProperitesTableSkelton } from '@/components/ui/DashboardPropertiesTable';
import { UserType } from '@/types';
import { PropertiesStatusFilterEnum } from '@/config';
type Props = {
currentPage: number;
userData: UserType | undefined;
status?: PropertiesStatusFilterEnum;
};
export default function DashboardProperitesMain({
currentPage,
userData,
status,
}: Props) {
return (
<section className=' max-w-[1300px] mx-auto '>
<Header />
<Suspense
key={`${currentPage}-${status}`}
fallback={<DashboardProperitesTableSkelton />}
>
<TableWrapper
status={status}
userData={userData}
currentPage={currentPage}
/>
</Suspense>
</section>
);
}
Table Wrapper:
import React from 'react';
import {
getAllProperitesAction,
getMyProperitesAction,
} from '@/server/property-actions';
import { DashboardPropertiesTable } from '@/components/ui/DashboardPropertiesTable';
import { UserType } from '@/types';
import { Roles } from '@/schemas';
import { PropertiesStatusFilterEnum } from '@/config';
type Props = {
currentPage: number;
userData: UserType | undefined;
status?: PropertiesStatusFilterEnum;
};
export default async function TableWrapper({
currentPage,
userData,
status,
}: Props) {
let properitesData;
if (userData?.role === Roles.ADMIN) {
properitesData = await getAllProperitesAction(
currentPage,
status
);
} else {
properitesData = await getMyProperitesAction(currentPage, status);
}
return (
<DashboardPropertiesTable
data={properitesData.data}
totalDocs={properitesData.totalDocs}
currentPage={currentPage}
/>
);
}