feat(landing): serve the landing page at /home for everyone - #39
Conversation
Share the landing metadata and structured data between the root and a new /home route so signed-in users can reach the marketing page directly, and list /home in the sitemap.
📝 WalkthroughWalkthroughShared landing-page metadata and JSON-LD helpers are added, the root and ChangesLanding SEO
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
apps/web/src/features/landing/landing-meta.test.ts (1)
14-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAvoid leaking
anyfromJSON.parse.
JSON.parseinfersdataasany, bypassing the strict typing requirement. Parse the payload through a small Zod schema before accessing its fields.As per coding guidelines,
**/*.{ts,tsx}must use strict types and must not useany.Suggested adjustment
+import { z } from 'zod'; + +const structuredDataSchema = z.object({ + '`@type`': z.literal('SoftwareApplication'), + offers: z.object({ price: z.string() }), + featureList: z.array(z.string()), +}); ... - const data = JSON.parse(landingStructuredData()); + const data = structuredDataSchema.parse(JSON.parse(landingStructuredData()));🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/features/landing/landing-meta.test.ts` around lines 14 - 17, Update the test around landingStructuredData to validate the parsed payload through a small Zod schema before accessing `@type`, offers.price, and featureList. Replace the direct JSON.parse result with the schema-validated typed value, ensuring no any escapes into the test while preserving the existing assertions.Source: Coding guidelines
apps/web/src/app/page.tsx (1)
6-6: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winNormalize both route metadata URLs through
absoluteUrl().
landingMetadata()copies its canonical argument directly intoalternates.canonicalandopenGraph.url, but both callers pass relative paths. Unless an app-levelmetadataBaseis guaranteed, verify or change these calls so generated metadata always uses the validated public origin.
apps/web/src/app/page.tsx#L6-L6: passabsoluteUrl('/')tolandingMetadata().apps/web/src/app/home/page.tsx#L4-L4: passabsoluteUrl('/home')tolandingMetadata().Based on learnings, public metadata URLs in
apps/web/srcshould useabsoluteUrl()so they share the validated, normalized public origin.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/app/page.tsx` at line 6, Normalize both landing metadata URLs through absoluteUrl: update the landingMetadata call in apps/web/src/app/page.tsx at line 6 to pass absoluteUrl('/') and the call in apps/web/src/app/home/page.tsx at line 4 to pass absoluteUrl('/home'), ensuring both canonical and Open Graph URLs use the validated public origin.Source: Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/features/landing/landing-meta.ts`:
- Line 2: Update landingMetadata to build canonical and Open Graph URLs with
absoluteUrl(canonical), and build the JSON-LD URL with absoluteUrl('/'); remove
the direct publicAppUrl() usage/import. Update landing-meta.test.ts assertions
to expect the resolved absolute URLs while preserving the existing route-path
input behavior.
---
Nitpick comments:
In `@apps/web/src/app/page.tsx`:
- Line 6: Normalize both landing metadata URLs through absoluteUrl: update the
landingMetadata call in apps/web/src/app/page.tsx at line 6 to pass
absoluteUrl('/') and the call in apps/web/src/app/home/page.tsx at line 4 to
pass absoluteUrl('/home'), ensuring both canonical and Open Graph URLs use the
validated public origin.
In `@apps/web/src/features/landing/landing-meta.test.ts`:
- Around line 14-17: Update the test around landingStructuredData to validate
the parsed payload through a small Zod schema before accessing `@type`,
offers.price, and featureList. Replace the direct JSON.parse result with the
schema-validated typed value, ensuring no any escapes into the test while
preserving the existing assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7c42d20e-0d0b-4f6c-b428-85ed3db50805
📒 Files selected for processing (5)
apps/web/src/app/home/page.tsxapps/web/src/app/page.tsxapps/web/src/app/sitemap.tsapps/web/src/features/landing/landing-meta.test.tsapps/web/src/features/landing/landing-meta.ts
Point the /home canonical and open graph url at the absolute root so the alias does not split search ranking, build every SEO url through absoluteUrl, and drop /home from the sitemap since it canonicalises to /.
Serve the landing page at /home so signed-in users can reach it too, sharing metadata with the root route.
Greptile Summary
This PR extracts the landing page metadata into a shared
landing-meta.tsmodule and adds a/homeroute so authenticated users (who are redirected away from/) can still reach the landing page.landingMetadata(canonicalPath)andlandingStructuredData()are pulled intoapps/web/src/features/landing/landing-meta.ts, eliminating the inline duplication that existed inapp/page.tsx./homeroute:apps/web/src/app/home/page.tsxrenders the landing page withlandingMetadata('/'), setting the canonical and Open Graph URL to/so search engines consolidate ranking on the root and not/home./homeis excluded from the sitemap.landing-meta.test.tsverifies that the canonical is an absolute URL, the page is indexable, and the Open Graph URL matches the canonical.Confidence Score: 5/5
Safe to merge. The change is a clean metadata extraction with a new unauthenticated-accessible route, no auth or data-handling paths are touched.
The refactor is mechanical: inline metadata moves to a dedicated module consumed identically by both routes. The /home route adds no new session logic, shares the same canonical URL as /, and is excluded from the sitemap. Tests cover the key invariants.
No files require special attention.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[User visits /] --> B{Authenticated?} B -- yes --> C[redirect to /my-issues] B -- no --> D[Render LandingPage with canonical /] E[User visits /home] --> F[Render LandingPage with canonical /] G[landingMetadata called with path /] --> H[absoluteUrl builds absolute root URL] H --> I[alternates.canonical = absolute root] H --> J[openGraph.url = absolute root] D & F -.->|both use| G K[Sitemap] --> L[Only / is listed]Reviews (2): Last reviewed commit: "fix(landing): canonicalise /home to the ..." | Re-trigger Greptile
Context used: