import type { Metadata } from 'next' import { notFound } from 'next/navigation' import { JsonLd } from '@/components/json-ld' import { ProjectNavigation } from '@/components/project-navigation' import { ToolsSection } from '@/components/sections/tools-section' import { WebsiteContentSection } from '@/components/website/website-content-section' import { WebsiteDetailSidebar } from '@/components/website/website-detail-sidebar' import { WebsiteDocsSection } from '@/components/website/website-docs-section' import { WebsiteError } from '@/components/website/website-error' import { WebsiteHero } from '@/components/website/website-hero' import { WebsiteRelatedProjects } from '@/components/website/website-related-projects' import { getWebsiteBySlug, getWebsites, type WebsiteMetadata } from '@/lib/content-loader' import { getRoute } from '@/lib/routes' import { generateWebsiteDetailSchema } from '@/lib/schema' import { generateDynamicMetadata } from '@/lib/seo/seo-config' interface ProjectPageProps { params: Promise<{ slug: string }> } /** * Generates metadata for the website page * * @param params - Page parameters containing the website slug * @returns Promise - Generated metadata for the page */ export async function generateMetadata({ params }: ProjectPageProps): Promise { const { slug } = await params try { const project = await getWebsiteBySlug(slug) if (!project) { return {} } // Format category for display const categoryFormatted = project.category ? project.category.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase()) : null // Create an SEO-optimized description const seoDescription = `${project.description} Explore ${project.name}'s llms.txt implementation for AI-ready documentation.${categoryFormatted ? ` Category: ${categoryFormatted}.` : ''}` // Generate comprehensive keywords const keywords = [ project.name, `${project.name} llms.txt`, `${project.name} AI documentation`, project.category, 'llms.txt', 'AI documentation', 'LLM integration', categoryFormatted ].filter(Boolean) as string[] return generateDynamicMetadata({ type: 'website', name: project.name, description: seoDescription.length > 160 ? project.description : seoDescription, slug: project.slug, additionalKeywords: keywords, publishedAt: project.publishedAt }) } catch (_error) { return { title: 'Website | llms.txt hub', description: 'Website information' } } } /** * Generates static parameters for all website pages * * @returns Promise> - Array of website slugs for static generation */ export async function generateStaticParams() { try { const websites = await getWebsites() if (!websites || websites.length === 0) { return [] } // Only include websites with valid string slugs const params = websites .filter((website: WebsiteMetadata) => website.slug && typeof website.slug === 'string') .map((website: WebsiteMetadata) => ({ slug: website.slug })) return params } catch (_error) { return [] } } /** * Website detail page component * * @param params - Page parameters containing the website slug * @returns Promise - Rendered website page */ export default async function ProjectPage({ params }: ProjectPageProps) { try { const { slug } = await params const project = await getWebsiteBySlug(slug) if (!project) { notFound() } const breadcrumbItems = [ { name: 'Websites', href: getRoute('website.list') }, { name: project.name, href: getRoute('website.detail', { slug: project.slug }) } ] return (
{/* Hero Section */} {/* Main Content Area */}
{/* Two-column grid: content + sidebar */}
{/* Main content column */}
{/* CLI Install + LLMs.txt Files */} {/* Content Section */} {/* Tools Section */}
{/* Sidebar column */}
{/* Full-width sections below the grid */}
{/* Navigation */}

Browse more

{/* Related Projects */} {project.relatedWebsites?.length > 0 && ( )}
) } catch (_error) { return } }