docs: drop /changelog from vitrine plan, flag in-app "what's new" gap
CHANGELOG.ts is a dev log (migration reminders, bug-fix jargon), not fit for public display. Removed the public changelog page from the vitrine's page list/rollout/PUBLIC_PATHS example. Added §6 flagging the real underlying need — a curated, in-app "What's New" surfaced to existing users (bell/badge, keyed off last-seen version) — as a separate, smaller feature to scope properly later, not folded into this plan.
This commit is contained in:
+25
-8
@@ -5,8 +5,7 @@
|
||||
**Current state, confirmed by reading the actual code, not assumed:**
|
||||
- `apps/web/app/page.tsx` — `/` unconditionally `redirect("/recipes")`, no marketing content exists.
|
||||
- `apps/web/proxy.ts` (the app's middleware, `export default proxy` + `config.matcher`) gates every path **not** in `PUBLIC_PATHS` behind a session cookie, redirecting straight to `/login`. `/` is not in that list — so today, an anonymous visitor hitting `/` never even reaches `page.tsx`'s redirect; they're bounced to `/login` first. **This is the one integration point that actually matters** — the vitrine is invisible to anonymous visitors until `PUBLIC_PATHS` changes.
|
||||
- No `/privacy`, `/terms`, `/about`, `/contact`, `/features`, `/pricing`, or public `/changelog` route exists anywhere.
|
||||
- `apps/web/lib/changelog.ts` already has a `CHANGELOG` array — currently only rendered at `/admin/changelog` (admin-only). Directly reusable for a public changelog page, no new data source needed.
|
||||
- No `/privacy`, `/terms`, `/about`, `/contact`, `/features`, or `/pricing` route exists anywhere.
|
||||
- No `sitemap.ts`/`robots.ts` — Next.js supports both as file-based special routes (same convention already used for `app/manifest.ts`, seen in that file) — currently missing entirely, worth adding as basic SEO hygiene regardless of how much content the vitrine ends up with.
|
||||
|
||||
---
|
||||
@@ -18,7 +17,6 @@
|
||||
| `/` | Home — hero, value prop, 3-4 feature highlights with screenshots, primary CTA → `/signup` |
|
||||
| `/features` | Deeper tour: AI recipe generation, meal planning, pantry tracking, social (follows/ratings/comments), the cooking assistant + its tool-calling (create recipe / add to shopping list from chat) |
|
||||
| `/pricing` | Free/Pro/Family comparison table, CTA into Checkout once Stripe ships (`STRIPE_PLAN.md` §5/§7), or straight to `/signup` before it does |
|
||||
| `/changelog` | Public version of the existing `CHANGELOG` data — social proof of active development, good for conversion and for existing users checking what's new |
|
||||
| `/about` | Story/mission — why this exists, who's building it |
|
||||
| `/privacy` | Privacy policy — needed once collecting emails regardless of Stripe timing (GDPR, since you're in France/EU per `STRIPE_PLAN.md` §10) |
|
||||
| `/terms` | Terms of service |
|
||||
@@ -41,7 +39,7 @@ Not in v1, deferred: a blog (`/blog`) — real SEO value but ongoing content-pro
|
||||
```ts
|
||||
const PUBLIC_PATHS = [
|
||||
"/login", "/signup", /* ...existing... */,
|
||||
"/", "/features", "/pricing", "/changelog", "/about", "/privacy", "/terms", "/contact",
|
||||
"/", "/features", "/pricing", "/about", "/privacy", "/terms", "/contact",
|
||||
];
|
||||
```
|
||||
Note `/` needs an **exact** match, not `startsWith` — the current check is `pathname.startsWith(p)`, which is fine for `/features` etc. (nothing else starts with those prefixes) but `"/"` as a prefix would make `PUBLIC_PATHS.some(p => pathname.startsWith(p))` true for literally every path, since every path starts with `/`. This needs a small tweak to the matching logic, not just an array addition — e.g. check `pathname === "/"` as its own condition alongside the `startsWith` list, don't add bare `"/"` into the array.
|
||||
@@ -52,7 +50,7 @@ Note `/` needs an **exact** match, not `startsWith` — the current check is `pa
|
||||
|
||||
## 3. SEO basics (currently entirely missing)
|
||||
|
||||
- `app/sitemap.ts` — list the 8 marketing routes (file-based Next.js route, same pattern as the existing `app/manifest.ts`).
|
||||
- `app/sitemap.ts` — list the 7 marketing routes (file-based Next.js route, same pattern as the existing `app/manifest.ts`).
|
||||
- `app/robots.ts` — allow marketing routes, disallow `/api`, `/admin`, `(app)` authenticated routes, `/r/`/`/s/`/`/u/` if those shouldn't be indexed (check current intent — they're public-but-unlisted-ish today, decide explicitly rather than defaulting).
|
||||
- Per-page `generateMetadata` (title/description/OpenGraph image) — every existing app page already sets `export const metadata: Metadata = {}` as a placeholder pattern; marketing pages should actually fill these in, they're the ones search engines/social shares see.
|
||||
- One shared OG image (or per-page) — doesn't need to be fancy, just present; a page with no OG image looks broken when shared on socials, more damaging than a plain one.
|
||||
@@ -71,6 +69,25 @@ Note `/` needs an **exact** match, not `startsWith` — the current check is `pa
|
||||
|
||||
1. `sitemap.ts`/`robots.ts` + the `PUBLIC_PATHS`/root-`page.tsx` change (§2–3) — plumbing first, still no real content, safe to ship and verify the routing/auth-gating logic works before writing copy.
|
||||
2. `/` (home) + `/features` — the two pages that actually sell the product; ship these before pricing exists if Stripe isn't live yet (CTA → signup, not checkout).
|
||||
3. `/changelog` — cheapest page to build (data already exists), good early win.
|
||||
4. `/privacy` + `/terms` + `/about` + `/contact` — required-but-not-persuasive pages, batch together.
|
||||
5. `/pricing` — once `STRIPE_PLAN.md` pricing (§1c) is confirmed and ideally once Checkout exists, so the CTA goes somewhere real instead of just to signup.
|
||||
3. `/privacy` + `/terms` + `/about` + `/contact` — required-but-not-persuasive pages, batch together.
|
||||
4. `/pricing` — once `STRIPE_PLAN.md` pricing (§1c) is confirmed and ideally once Checkout exists, so the CTA goes somewhere real instead of just to signup.
|
||||
|
||||
---
|
||||
|
||||
## 6. Separate concern: advertising new features to existing users
|
||||
|
||||
Not part of this plan (in-app, not public/marketing), but flagged since it
|
||||
came up here: `apps/web/lib/changelog.ts`'s `CHANGELOG` array is written
|
||||
for you, not users — entries mix real feature announcements with internal
|
||||
notes ("not applied in sandbox — run `pnpm db:migrate`", bug-fix jargon,
|
||||
migration reminders). That's correctly *not* public. But there's a real
|
||||
gap: users have no clean way to learn what shipped since they last looked.
|
||||
|
||||
Direction for later, not scoped in detail here: a curated, user-facing
|
||||
"What's New" — either a hand-picked subset/rewrite of `CHANGELOG` entries
|
||||
(only the ones worth telling a user about, in plain language, not the raw
|
||||
dev log) or a separate small table if the two need to diverge more than a
|
||||
filter allows. Surfaced in-app — a badge/dot on a bell icon, a dismissible
|
||||
panel on next login, keyed off "last version the user has seen" so it only
|
||||
shows genuinely new items. This is a distinct, smaller feature from the
|
||||
vitrine and can be scoped properly in its own pass.
|
||||
|
||||
Reference in New Issue
Block a user