+ {/* Preview Banner */}
+ {isPreview && (
+
+ Preview Mode — This page is {page.status}. Only you can see this preview.
+
+ )}
+ {/* Navbar */}
+ {navbarSection &&
+ (() => {
+ const transformed = transformSection(navbarSection);
+ if (!transformed) return null;
+ return
;
+ })()}
+
+ {/* Main content sections */}
+
+ {contentSections.map((section) => {
+ const transformed = transformSection(section);
+ if (!transformed) return null;
+
+ // Type-safe rendering based on slot
+ switch (transformed.slot) {
+ case 'hero':
+ return ;
+ case 'features':
+ return (
+
+ );
+ case 'cta':
+ return ;
+ case 'about':
+ return ;
+ default:
+ return null;
+ }
+ })}
+
+
+ {/* Footer */}
+ {footerSection &&
+ (() => {
+ const transformed = transformSection(footerSection);
+ if (!transformed) return null;
+ return
;
+ })()}
+
+ );
+}
diff --git a/apps/ottabase-template-app-nextjs-homepage/app/[slug]/page.tsx b/apps/ottabase-template-app-nextjs-homepage/app/[slug]/page.tsx
new file mode 100644
index 000000000..789e8e55a
--- /dev/null
+++ b/apps/ottabase-template-app-nextjs-homepage/app/[slug]/page.tsx
@@ -0,0 +1,69 @@
+/**
+ * Dynamic Marketing Page Route
+ *
+ * Handles marketing pages created via Admin → Marketing Pages.
+ * Fetches page data from /api/pages/:slug and renders block-based layouts.
+ *
+ * Routes:
+ * - /{slug} → This component (e.g., /pricing, /about-us, /features)
+ * - / (homepage) → app/(site)/page.tsx
+ * - /page/{slug} → app/page/[slug]/page.tsx (ottablog content pages)
+ */
+import type { Metadata } from 'next';
+import { notFound } from 'next/navigation';
+import { fetchPageByPageSlug } from '../../lib/api';
+import { MarketingPageContent } from './marketing-page-content';
+
+interface PageProps {
+ params: Promise<{ slug: string }>;
+ searchParams: Promise<{ preview?: string }>;
+}
+
+export async function generateMetadata({ params, searchParams }: PageProps): Promise