← back to Grant
Serve fit-feed landing at / for logged-out visitors; AppShell for signed-in (shared Landing component)
f42a32602436a02b0386a2c0ec17854e65abf474 · 2026-05-30 09:21:04 -0700 · Steve Abrams
Files touched
M app/landing/page.tsxM app/page.tsxA components/landing/Landing.tsxR100 app/landing/landing.css components/landing/landing.css
Diff
commit f42a32602436a02b0386a2c0ec17854e65abf474
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat May 30 09:21:04 2026 -0700
Serve fit-feed landing at / for logged-out visitors; AppShell for signed-in (shared Landing component)
---
app/landing/page.tsx | 24 ++----------------------
app/page.tsx | 14 ++++++++++++--
components/landing/Landing.tsx | 30 ++++++++++++++++++++++++++++++
{app => components}/landing/landing.css | 0
4 files changed, 44 insertions(+), 24 deletions(-)
diff --git a/app/landing/page.tsx b/app/landing/page.tsx
index 699a659..1e42d43 100644
--- a/app/landing/page.tsx
+++ b/app/landing/page.tsx
@@ -1,21 +1,5 @@
import type { Metadata } from 'next';
-import { Space_Grotesk, IBM_Plex_Sans } from 'next/font/google';
-import FitFeed from '@/components/landing/FitFeed';
-import './landing.css';
-
-const display = Space_Grotesk({
- subsets: ['latin'],
- weight: ['500', '600', '700'],
- variable: '--ff-display',
- display: 'swap',
-});
-
-const body = IBM_Plex_Sans({
- subsets: ['latin'],
- weight: ['400', '500', '600'],
- variable: '--ff-body',
- display: 'swap',
-});
+import Landing from '@/components/landing/Landing';
export const metadata: Metadata = {
title: 'Grant — One fit-scored feed for every funding source',
@@ -24,9 +8,5 @@ export const metadata: Metadata = {
};
export default function LandingPage() {
- return (
- <div className={`${display.variable} ${body.variable}`}>
- <FitFeed />
- </div>
- );
+ return <Landing />;
}
diff --git a/app/page.tsx b/app/page.tsx
index c6bdf56..f374e8f 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,5 +1,15 @@
+import { headers } from 'next/headers';
import AppShell from '@/components/AppShell';
+import Landing from '@/components/landing/Landing';
+import { verifyAuth } from '@/lib/auth';
-export default function Home() {
- return <AppShell />;
+// Auth-branch the root route: signed-in visitors get the app; everyone else
+// sees the public fit-feed landing. verifyAuth only reads the `cookie` header,
+// so we hand it a minimal shim built from the incoming request headers.
+export default async function Home() {
+ const cookie = (await headers()).get('cookie') ?? '';
+ const shim = { headers: { get: (k: string) => (k.toLowerCase() === 'cookie' ? cookie : null) } };
+ const session = verifyAuth(shim as unknown as Request);
+
+ return session ? <AppShell /> : <Landing />;
}
diff --git a/components/landing/Landing.tsx b/components/landing/Landing.tsx
new file mode 100644
index 0000000..0082478
--- /dev/null
+++ b/components/landing/Landing.tsx
@@ -0,0 +1,30 @@
+import { Space_Grotesk, IBM_Plex_Sans } from 'next/font/google';
+import FitFeed from './FitFeed';
+import './landing.css';
+
+/* Shared public marketing landing — rendered both at /landing and at / for
+ logged-out visitors (app/page.tsx auth-branches to it). Fonts are
+ self-hosted via next/font and exposed to landing.css as --ff-display /
+ --ff-body on the wrapper. */
+
+const display = Space_Grotesk({
+ subsets: ['latin'],
+ weight: ['500', '600', '700'],
+ variable: '--ff-display',
+ display: 'swap',
+});
+
+const body = IBM_Plex_Sans({
+ subsets: ['latin'],
+ weight: ['400', '500', '600'],
+ variable: '--ff-body',
+ display: 'swap',
+});
+
+export default function Landing() {
+ return (
+ <div className={`${display.variable} ${body.variable}`}>
+ <FitFeed />
+ </div>
+ );
+}
diff --git a/app/landing/landing.css b/components/landing/landing.css
similarity index 100%
rename from app/landing/landing.css
rename to components/landing/landing.css
← 5692f38 Build out fit-feed landing as real /landing route (interacti
·
back to Grant
·
SEO (robots/sitemap/OG image/metadata) + reusable deploy.sh 580b213 →