Nothing yet.
Changelog
Everything new in Lighthouse. We ship small, often, and write it down. Calendar-versioned as YEAR.ISOWEEK.RELEASE.
- AI analysis switched from gpt-5 to gpt-4o-mini. gpt-5 is a reasoning model and structured-output calls were taking 30 to 60 seconds per click, which is unusable for a live demo and reads as broken to the user. gpt-4o-mini returns in 2 to 4 seconds at roughly the same quality for this workload (summarising 50 to 500 short survey answers into 3 themes + 3 segments + 5 phrases + 3 signals). Response arrays now have explicit
maxItemscaps so output tokens stay bounded regardless of the input size. Loading copy on the button updated to "a few seconds" instead of "10 to 20 seconds".
- AI analysis of waitlist survey answers (Pro). New "Analyze with AI" button on the waitlist detail page inside the dashboard. One click sends the waitlist's survey questions, all signup answers, free-text notes, signup count, and date range to OpenAI (
gpt-5) and renders a structured report with five sections: Overall summary, Top pain themes with example quotes, Audience segments, Common language chips, and Signals worth watching. Gated to Pro accounts viahasMinTier(price_id, "pro"); non-Pro tier sees a locked card linking to pricing. Trigger is manual click only, no auto-run. Email addresses are stripped before the payload leaves the server, only survey answers, notes, and timestamps reach OpenAI. RequiresOPENAI_API_KEYin Vercel env. New files:libs/openai.ts,app/dashboard/projects/[id]/ai-actions.ts,app/dashboard/projects/[id]/components/AIAnalyzeButton.tsx.
- Twitter card preview showed the sitewide default image on every blog article.
getSEOTagswas readingopenGraph?.imagesfrom the direct parameter when computingtwitter.images, but blog articles pass theiropenGraphobject insideextraTags(that shape came from the ShipFast template). So the direct-parameter read was always undefined and Twitter fell back toopengraph-image.pngeven thoughog:imagecorrectly showed the article hero.libs/seo.tsxnow extracts the effective OG images from both the direct param andextraTags.openGraph.images, and mirrors that value into bothopenGraph.imagesandtwitter.images. Shared blog articles now show the correct article hero on X, LinkedIn, Slack, and every other Open Graph consumer.
- Datafa.st analytics missing on static pages. The
2026.28static-render pass moved/,/blog/[articleId],/about,/docs,/tos,/privacy-policy, and/securitytodynamic = "force-static".DatafastSlotwas gating onheaders().get("host"), which returns empty during prerender, so the tracking script was dropped from every static page and only survived on/blog(which uses ISR). Replaced the server-side host gate with an inline browser-runtime gate: the<Script>tag is now unconditionally emitted, and a small inline check only injects the Datafa.st script whenlocation.hostnamematches a Lighthouse host. Custom-domain visitors still don't load the tag. Same regression applied toDiscordPillSlot; the redundant server-side host gate has been removed becauseDiscordPillalready hides on/w,/s,/n,/fviausePathname, which is where custom-domain visitors always land.
- Static-rendered marketing and blog pages. Added
dynamic = "force-static"(anddynamicParams = falsewhere applicable) to/,/blog/[articleId],/blog/category/[categoryId],/about,/docs,/tos,/privacy-policy, and/security./blogusesrevalidate = 3600becausesearchParamspagination blocks full static. Vercel now prerenders these routes at deploy instead of computing them per-request. Observed Active CPU on/(was 8s across 67 invocations) and/blog/[articleId](was 4.31s across 52 invocations) drops to near zero.
- Landing hero rebuilt around a single CTA. The three floating dashboard preview cards ("Top request", "Cal AI waitlist", "New signup") are removed. The hero now leads with a single H1 -- "Transform that *late-night idea* into an audience waiting *for you to ship*" with yellow-highlighted phrases -- a tighter subhead about waitlists and surveys, a white "Get Started" CTA, and a "Get your first 10 users" note (Seth Godin's "First, ten" framing, per team audit).
- Top-nav simplified. The duplicate "Get started" button is removed from the desktop header so the hero CTA is the single conversion path above the fold. The "Dashboard" link is renamed "Sign in" and remains for returning users. (Mobile nav drawer untouched.)
- Blog post: Substack vs Lighthouse: which fits an indie launch (2026). Honest comparison framing Substack as a publication platform and Lighthouse as a launch toolkit, with four founder personas and an honest note about when fundraising founders should reach for neither. Cites Spaceport in the intro and Funding Banker mid-text.
- RSS feed for the blog. New endpoint at
/blog/rss.xmlserves a static RSS 2.0 feed with every published article (newest first), properdc:creatorandcategorytags, and an RFC 822pubDatederived from each post'spublishedAt. The blog header gets a small RSS icon link, and<link rel="alternate" type="application/rss+xml">is emitted in every blog page's<head>for feed-reader auto-discovery. Middleware matcher updated per SEO Rule 7 so the feed bypasses the auth layer.
- Optional email on waitlists. New
Require emailtoggle on the waitlist create and edit forms (default on, so existing waitlists keep behaving the same). When off, the public signup form labels the email field as optional and lets visitors submit just the survey answers and free-text note. Useful for early validation when you care more about answers than email addresses. Migration0016addswaitlists.email_requiredand makeswaitlist_signups.emailnullable. - "Powered by Lighthouse" in the footer of every public share page (waitlist, survey, newsletter, feedback) is now a link to the Lighthouse landing page.
- Yearly billing for Starter and Pro. Pricing section gains a segmented Monthly / Yearly toggle above the cards. Yearly is priced as 10 months ($190 for Starter, $290 for Pro -- 2 months free), labeled as such on the toggle. Same 7-day trial applies.
tierFromPriceIdnow recognises both monthly and yearly Stripe price IDs as the same tier so feature gating works regardless of billing interval. JSON-LD offers expanded to include yearly variants.
- 7-day free trial on every subscription. Card is collected at checkout (Stripe does a zero-amount auth to validate), $0 charged for the first 7 days, then auto-charges the full price on day 8. Cancel anytime during the trial via the customer portal with no charge. Pricing CTAs now read "Start 7-day free trial" and the hero blurb leads with "Try free for 7 days".
- Free tier removed from public pricing. The landing pricing section and WebApplication JSON-LD offers no longer surface the free plan to new visitors. Existing free-tier accounts continue to work exactly as before -- only the marketing presentation changed. The pricing grid is now a balanced 2-up of Starter and Pro.
- Dashboard redesigned around square project tiles. The flat row list is replaced by a responsive grid of cards (1 / 2 / 3 columns at breakpoints). Each tile shows the logo, name, URL, a Live / Draft chip, and a 2x2 stats grid: Signups, Subs, Survey, Feedback. The "+ New project" button now also slots into the grid as a dashed tile with plan-usage indicator. Adds filter pills (All / Live / Drafts) with counts. Live = the project has at least one waitlist, survey, newsletter, or feedback collector created; Draft = empty project. Counts are fetched in parallel via embedded count queries with one round-trip per asset type.
- Sidebar switched to a dark theme to match the Notion-inspired direction. Active nav item gets a mint accent, hover shows a subtle white tint, icons brighten on hover and active. The mobile drawer follows the same palette.
- Archived projects view. Deleting a project now archives it instead of removing it immediately. A new
/dashboard/archivepage lists archived projects with restore and "delete permanently" actions. Free-plan customers see a notice that archives are pending deletion after 3 days. The main dashboard adds a "View archived (N)" link below the project list when there are any.
- Per-page brand colour on share pages. Each waitlist, survey, newsletter, and feedback collector now stores its own background colour. The chosen colour drives the public page background and derives the CTA gradient, focus rings, selected states, and hover backgrounds via CSS
color-mix(). Picking one colour themes the entire form. Dashboard adds a six-swatch picker plus a custom-hex input just below the existing logo control, with a low-contrast warning for very light colours.
- Public share pages redesigned.
/w/[slug],/s/[slug],/n/[slug], and/f/[slug]now use a wider Notion-style layout (max-w-2xl), softer shadow, top-left logo, and accent-driven form fields. The narrow centred card is gone.
- Waitlists. Public signup at
/w/[slug]with an optional free-form note field and an optional per-question survey gating signup. Dashboard CRUD, CSV export, "launch" workflow. - Surveys. Standalone forms at
/s/[slug]with multi-step wizard, optional email capture, and configurable button text. - Newsletter campaigns. Subscriber lists with manual / CSV / waitlist / API sources. Campaign composer with chunked Resend sending, sent-count tracking, signed unsubscribe tokens.
- Feedback collector. Public form at
/f/[slug]with stars or thumbs rating, configurable categories, optional email, and anew → read → triaged → shippedstatus workflow with operator-visible "Shipped in v1.2" notes. - REST API at
/api/v1/. Bearer-token auth via SHA-256 hashed keys. Endpoints for waitlist signups, survey responses, newsletter subscribers, feedback submissions. Gated to the Pro plan via theprice_idon the profile. - Custom domains. Pro customers can point their own subdomain at any waitlist, survey, feedback, or newsletter page via a single CNAME record. Live lookup runs in middleware.
- Blog at `/blog` with Outrank integration, native
app/sitemap.ts,app/robots.ts,llms.txt, AI-crawler allowlist, and Article + WebApplication + FAQ JSON-LD on every relevant page. - Datafast analytics scoped to Lighthouse-owned hosts only, with
datafast_visitor_idanddatafast_session_idcookies forwarded as Stripe Checkout metadata so subscription revenue ties back to the original visitor. - Auth and billing. Magic-link only sign-in, gated by
has_access. Pay-first Stripe Checkout withinviteUserByEmailoncheckout.session.completed. Customer portal for self-serve plan changes and cancellation. Webhook handlers for the full subscription lifecycle.
Following Keep a Changelog 1.1.0. Spotted something missing? Tell us.