Files
zeekay 35414cc434 Every course /university lists has a page, and /university, its courses and /compare say what they are
/university linked /university/agentic-marketing, /ai-practitioner and
/ai-architect, and the export had no page for any of them: `[slug]` built
UNIVERSITY_COURSES alone and the three are ADDITIONAL_COURSES (dca52d60).
It builds every course but agentic-coding, which has its own page.

/university, /university/agentic-coding and /compare inherited the
marketing layout's title, the same tab and search result three times. Each
takes its <h1> and lede through pageMeta, and a course page names its own
path as canonical rather than inheriting /university's.
2026-10-15 09:41:46 -07:00

42 lines
1.3 KiB
TypeScript

import { notFound } from 'next/navigation'
import type { Metadata } from 'next'
import { COURSE_PAGES } from '../courses-data'
import { CourseView } from './CourseView'
import { pageMeta } from '@/lib/page-meta'
export function generateStaticParams() {
return COURSE_PAGES.map((c) => ({ slug: c.slug }))
}
function findCourse(slug: string) {
return COURSE_PAGES.find((c) => c.slug === slug)
}
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>
}): Promise<Metadata> {
const { slug } = await params
const course = findCourse(slug)
if (!course) return { title: 'Course Not Found — Hanzo University' }
// Its own path as its canonical: /university's layout names /university, and
// a page that inherits it tells a crawler it is that page.
return pageMeta({
title: `${course.code}: ${course.title} (${course.credential})`,
description: `${course.summary} Earn your ${course.credential} credential with 25% compute credit rebate and isolated Hanzo Visor sandboxes.`,
path: `/university/${course.slug}`,
})
}
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
const course = findCourse(slug)
if (!course) notFound()
return <CourseView course={course} />
}