Skip to main content

Skeleton loader

A skeleton is essentially a lightweight, placeholder layout that mimics the shape of the content being loaded, giving users a visual structure to look at while they wait for the actual content.

Dynamic Imports with Skeletons

For components that are loaded dynamically using next/dynamic, you can provide a skeleton as a fallback while the component is being fetched.

import dynamic from 'next/dynamic';

// Use a Skeleton as a loading placeholder
const DynamicComponent = dynamic(() => import('../components/HeavyComponent'), {
loading: () => <SkeletonCard />, // Show skeleton while loading
});

function HomePage() {
return (
<div>
<h1>Home Page</h1>
<DynamicComponent />
</div>
);
}

export default HomePage;

Using Server Components and Suspense with Skeletons

  • Create a Skeleton Component: This component mimics the layout of the actual content and is displayed while data is loading.
  • Create an Async Component to Fetch Data: Use a server component to fetch the data, and wrap it with React’s <Suspense> to show the skeleton while loading.
  • Use the Async Component in the Page: Integrate the server-side fetched component with Suspense and the Skeleton.
import { Suspense } from 'react';
import CourseSkeleton from './CourseSkeleton';

// Server Component to fetch and display courses
async function CourseList() {
const courses = await fetchCourses(); // Fetch data on the server
return (
<div className="course-list">
{courses.map((course) => (
<div key={course.id} className="course-card">
<div className="course-image">{/ Display course image /}</div>
<h2>{course.name}</h2>
<p>Price: ${course.price}</p>
</div>
))}
</div>
);
}

// Page component that uses Suspense with the skeleton
export default function CoursePage() {
return (
<Suspense fallback={<CourseSkeleton />}>
<CourseList />
</Suspense>
);
}