Refactoring Next.js App Router: Fixing Waterfalls, Duplicate Queries, and Cache Invalidation
When building dynamic applications with the Next.js App Router, it’s surprisingly easy to slip into anti-patterns that silently degrade performance and balloon your database queries.
In this case study, we refactor a high-traffic course detail page in Next.js 15—fixing duplicate fetching, sequential promise waterfalls, and caching misconfigurations.
🚩 The Original Code
Here was the starting point: a server-rendered route handling dynamic metadata, profile queries, and enrollment-based redirection logic.
// app/courses/[slug]/page.tsxexport const dynamic = "force-dynamic";export async function generateMetadata({params,}: {params: Promise<{ slug: string }>;}) {const { slug } = await params;const supabase = createStaticClient();const course = await getCourseBySlug(slug, supabase);if (!course) {return { title: "Course Not Found" };}return {title: `${course.name} | ${APP_NAME}`,description: course.description,};}export default async function CourseDetailPage({params,}: {params: Promise<{ slug: string }>;}) {const { slug } = await params;const course = await getCourseBySlug(slug);if (!course) {notFound();}const user = await getUser();const supabase = await createClient();// Get user profile if authenticatedlet profile = null;if (user) {const { data } = await supabase.from("profiles").select("role").eq("id", user.id).single();profile = data;}// Check if user is enrolledlet isEnrolled = false;if (user) {const { data: dbCourse } = await supabase.from("courses").select("id").eq("slug", slug).maybeSingle();if (dbCourse) {const { data: enrollment } = await supabase.from("enrollments").select("id, expires_at").eq("user_id", user.id).eq("course_id", dbCourse.id).eq("status", "active").or(`expires_at.is.null,expires_at.gt.${new Date().toISOString()}`).maybeSingle();isEnrolled = !!(!!enrollment ||(profile?.role === "premium" && course.isFreeForPremium));}}if (isEnrolled) {redirect(`/dashboard/courses/${slug}`);}return <CourseView course={course} />;}