feat: URL-driven catchall routing, drop sidebar nav, split export build

- app/[[...slug]]/page.tsx replaces app/page.tsx; activeSlug from URL params
- SidebarNav and MobileNav removed from main layout (sections accordion is the nav)
- next.config.ts: output:export controlled by STATIC_EXPORT env var instead of NODE_ENV
- package.json: yarn build is standard Next.js build; yarn export is STATIC_EXPORT=true
- Mock API route: force-static + generateStaticParams for output:export compatibility
This commit is contained in:
Ilia Mashkov
2026-05-11 11:12:21 +03:00
parent af165ec356
commit fed9c97ddb
4 changed files with 60 additions and 4 deletions
+50
View File
@@ -0,0 +1,50 @@
import { notFound } from 'next/navigation';
import type { SectionRecord } from '$entities/Section';
import { getCollection } from '$shared/api';
import { SectionFactory } from '$widgets/SectionFactory';
import { SectionsAccordion } from '$widgets/SectionsAccordion';
/**
* Optional catchall: `/` → first section, `/:slug` → that section.
*/
export async function generateStaticParams() {
const { items: sections } = await getCollection<SectionRecord>('sections', {
sort: 'order',
});
return [{}, ...sections.map((s) => ({ slug: [s.slug] }))];
}
type Props = {
params: Promise<{ slug?: string[] }>;
};
/**
* Portfolio page — one route per section, sections list always visible.
*/
export default async function SectionPage({ params }: Props) {
const { slug } = await params;
const { items: sections } = await getCollection<SectionRecord>('sections', {
sort: 'order',
});
if (sections.length === 0) {
notFound();
}
const activeSlug = slug?.[0] ?? sections[0].slug;
if (!sections.some((s) => s.slug === activeSlug)) {
notFound();
}
return (
<main className="px-8 py-12 lg:py-16 lg:px-16">
<SectionsAccordion sections={sections} activeSlug={activeSlug}>
{sections.map((s) => (
<SectionFactory key={s.slug} slug={s.slug} />
))}
</SectionsAccordion>
</main>
);
}
@@ -1,6 +1,6 @@
import { NextResponse } from 'next/server';
export const dynamic = 'force-dynamic';
export const dynamic = 'force-static';
const base = { created: '', updated: '' };
@@ -241,6 +241,10 @@ const FIXTURES: Record<string, unknown[]> = {
],
};
export function generateStaticParams() {
return Object.keys(FIXTURES).map((collection) => ({ collection }));
}
/**
* Mock API route handler for PocketBase collection records.
* Returns fixture data shaped as a PocketBase list response.