;\n })}\n \n );\n}and this is the page with the suspense boundary:import { Suspense } from \"react\";\nimport ResultGrid from \"@/components/explore/ResultGrid\";\n\nexport default function Explore({\n searchParams,\n}: {\n searchParams: ExploreSearchParams;\n}) {\n return (\n
import { getRandomFilm } from "@/lib/film";
import FilmResult from "./FilmResult";
async function getFilms(n: number) {
let films: Film[] = [];
for (let i = 0; i < n; i++) {
films[i] = await getRandomFilm();
}
await new Promise((resolve) => setTimeout(resolve, 5000));
return films;
}
export default async function ResultGrid({
searchParams,
}: {
searchParams: ExploreSearchParams;
}) {
const films = await getFilms(8);
return (
<div className="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))]">
{films.map((film) => {
return <FilmResult key={film.slug} film={film} />;
})}
</div>
);
}
import { Suspense } from "react";
import ResultGrid from "@/components/explore/ResultGrid";
export default function Explore({
searchParams,
}: {
searchParams: ExploreSearchParams;
}) {
return (
<main>
<Suspense
fallback={
<div className="text-5xl font-bold text-red-600">LOADING...</div>
}
>
<ResultGrid searchParams={searchParams}></ResultGrid>
</Suspense>
</main>
);
}
await new Promise((resolve) => setTimeout(resolve, 5000 * Math.random()));
export default async function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
{Array.from({ length: 8 }).map((_, i) => (
<Suspense key={i} fallback={<div>loading...</div>}>
<Child id={i} />
</Suspense>
))}
</main>
);
}
async function Child({ id }: { id: number }) {
await new Promise((resolve) => setTimeout(resolve, 5000 * Math.random()));
return <div>{id}</div>;
}
loading...
appears then is replaced or is gone.loading.tsx
import { render } from "@react-email/render";
import { Suspense } from "react";
export const dynamic = "force-dynamic";
export function generateStaticParams() {
return Array.from({ length: 8 }).map((_, i) => ({ name: String(i + 1) }));
}
export default async function Home({ params }: { params: { name: string } }) {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
{Array.from({ length: 8 }).map((_, i) => (
<Suspense key={i} fallback={<div>loading...</div>}>
<Child name={params.name} />
</Suspense>
))}
</main>
);
}
async function Child({ name }: { name: string }) {
const markup = await getComponent(name);
await new Promise((resolve) => setTimeout(resolve, 5000 * Math.random()));
return <div dangerouslySetInnerHTML={{ __html: markup }}></div>;
}
async function getComponent(name: string) {
const Email = (await import(`../../../email/${name}/twitch`)).default;
const markup = await new Promise((resolve) =>
resolve(render(<Email />, { pretty: true }))
);
// const markup = render(<Email />, { pretty: true });
return markup as string;
}