Skip to content

feat: prerender per-component pages for SEO (vite-ssg) - #2

Merged
Jettonn merged 2 commits into
feat/input-components-and-cifrom
feat/component-pages-ssg
Jul 17, 2026
Merged

feat: prerender per-component pages for SEO (vite-ssg)#2
Jettonn merged 2 commits into
feat/input-components-and-cifrom
feat/component-pages-ssg

Conversation

@Jettonn

@Jettonn Jettonn commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Stacked on #1 (targets feat/input-components-and-ci; GitHub will retarget to main once #1 merges).

Why

The SEO audit found the decisive issue: the site was a client-rendered SPA, so crawlers and AI bots that don't run JS saw an empty <div id="app"> — ~8 words, zero headings. Every strong meta tag wrapped an empty body, and the sitemap held a single URL.

What

  • Prerendering via vite-ssg + vue-router/ and /components/<slug> build to real static HTML. 16 pages now, up from 1.
  • Per-route <head> with unhead: unique title, description, canonical, OG/Twitter, plus BreadcrumbList + SoftwareSourceCode JSON-LD per component.
  • Component catalog (src/catalog.ts) — single source of truth for the gallery, detail pages, CLI install picker (was stale, missing the 4 new components), and the sitemap.
  • Layout splitApp.vue becomes header/footer/theme shell; Home.vue + ComponentDetail.vue are views. Gallery cards deep-link to detail pages (internal linking). Live demos are client-only so prerendered HTML stays text.
  • Sitemap generated from the registry at build (home + every component page).
  • Tailwind v4 → official Vite plugin so CSS resolves in the SSR build; overridable head tags moved out of index.html to avoid duplicate tags.

Verification

  • 16 static pages build; home + component prose render server-side (checked the raw HTML).
  • Live in a browser: no hydration warnings, no duplicate title/description tags, detail og:type correctly overrides to article, install picker preselects, demos + theme intact.
  • type-check, lint:check, format:check, build all green.

SEO impact

Directly resolves the audit's Critical (empty shell → real content for non-JS bots incl. AI crawlers) and High (1 URL → 16, long-tail keywords per component) findings.

The site was a client-rendered SPA: crawlers and AI bots that don't run
JS saw an empty <div id="app"> — every good meta tag wrapped no body.
This adds static prerendering and one indexable page per component,
turning a single URL into 16.

- Adopt vite-ssg + vue-router; prerender / and /components/<slug> to
  real HTML with per-route <head> (title, description, canonical, OG,
  BreadcrumbList + SoftwareSourceCode JSON-LD) via unhead
- Add a component catalog as the single source of truth for the gallery,
  the detail pages, the CLI install picker and the sitemap
- Split App.vue into a layout (header/footer/theme) + Home and
  ComponentDetail views; cards deep-link to their pages for internal
  linking; live demos stay client-only so prerendered HTML is text
- Generate sitemap.xml from the registry at build (home + every page)
- Switch Tailwind v4 to its official Vite plugin so CSS resolves in the
  SSR build; move overridable head tags out of index.html to avoid
  duplicate tags

Home body and all component prose now render server-side; verified no
hydration warnings and no duplicate meta tags.
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
verve Ready Ready Preview, Comment Jul 17, 2026 9:46am

Swap arbitrary values for their v4 shorthand tokens across the
components and site:

- opacity modifiers: /[0.04] -> /4, /[0.06] -> /6, /[0.07] -> /7,
  /[0.10] -> /10, /[0.02] -> /2
- transition duration: duration-[400ms] -> duration-400
- CSS variable: max-h-[var(--h)] -> max-h-(--h)

Compiled CSS is byte-for-byte equivalent (verified max-height:var(--h)
and .duration-400 in the build output); this only clears the editor
"can be written as" hints.
@Jettonn
Jettonn merged commit c973962 into feat/input-components-and-ci Jul 17, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant