Commit Graph

9 Commits

Author SHA1 Message Date
David Montero 2c43c638a1 prerender: SSR bodies were never injected; examples gallery renders on the server
replaceRootSeo() swaps the static #root-seo fallback for the page's SSR
body by string search. The old regex required a <script> right after the
block, but Vite hoists the module script into <head> in the built
index.html, so it never matched: every prerendered page (landings, /v3,
/about, all 171 example pages) shipped the HOMEPAGE's fallback body —
same <h1>, same nav — under its own <head>. Two hundred near-duplicate
bodies, and none of the landings' actual content (h1, sections, FAQ)
ever reached the crawler.

ExamplesGallery passes a server snapshot to useSyncExternalStore so
/examples SSRs instead of falling back to meta-only.
2026-08-18 18:10:36 +02:00
David Montero e1fc833f61 seo: starter examples are "New <board> project" pages
data/starters.ts maps eight free boards to the gallery example that opens
the editor with the board and a working blink (blink-led, nano-blink,
mega-blink, esp32-blink-led, esp32s3-blink-led, c3-blink, pico-blink,
attiny85-blink). ExampleEditorPage gives those ids an action-shaped
title/description ("New ESP32 project — free online ESP32 simulator")
while the gallery keeps the sketch title; the prerender writes
dist/starters.json so the prod app shell can serve the same head in the
raw HTML. This is the Wokwi "New ESP32 Project" shape: a URL of its own,
canonical of its own, that lands inside the product with the board loaded
— a candidate for brand sitelinks with usage intent.
2026-08-18 17:38:13 +02:00
David Montero 6f19cf9068 seo: /v2 and /v2-5 canonical to the home and out of the sitemap
Superseded release pages that were taking two brand sitelink slots (5.9k
impressions, 29 clicks). They still render for old links; hreflang is
only emitted for a page that is its own canonical (prerender + useSEO).
2026-08-18 17:29:54 +02:00
David Montero 54e25cfed5 seo: seo-routes.json lists every SEO route with metadata, not only the prerendered ones
So the prod app shell can give a route that has metadata but (yet) no
prerendered file its own head, self canonical and hreflang instead of the
homepage's.
2026-08-18 17:21:12 +02:00
David Montero 4da00840c6 seo: own-locale canonical + hreflang for localized pages; /editor prerendered
- useSEO: for the static SEO routes (marketing pages, examples gallery,
  editor, home) the canonical is now the page's OWN locale variant and the
  head lists every locale variant as rel=alternate hreflang plus x-default
  on the locale-less English URL. /es/ and /zh-cn/ were declaring
  canonical=/ while Google indexed and ranked them on their own — an
  unstable contradiction. UGC pages (projects, profiles, example detail
  pages) are the same English content under every prefix and keep a single
  locale-less canonical with no hreflang.
- prerender-seo.mjs emits the same hreflang set into each prerendered page
  and writes dist/seo-routes.json (path/title/description) so the prod app
  shell can serve the /<locale>/<route> variants (which have no static file)
  with the route's own head.
- /editor gets seoMeta and a static SSR summary component, so it is
  prerendered: nginx now serves /editor/ as a real page and 301s /editor to
  it. Both forms answered 200 with the homepage head before, and Google
  indexed /editor and /editor/ as two pages.
2026-08-18 16:50:39 +02:00
David Montero Crespo b70bb8ab83 refactor(routes): OSS is the editor; marketing moves to the overlay
The open-source build now ships exactly its product surface: /editor, the
examples gallery (/examples, /examples/:id) and the per-example editor
(/example/:id). Landing, about, pricing, docs, the 14 keyword-targeted
simulator landings and the v2/v2.5/v3 showcases move to the private
overlay, registered through the same registerProRoutes seam that already
carries login/admin/classroom.

Root behaves per build: an overlay that registers an index route claims
'/' (velxio.dev keeps its landing); otherwise '/' redirects to /editor.
The redirect waits for the overlay import to settle — same contract as
markProExamplesSettled — so a velxio.dev visitor is never bounced into
the editor because the landing was 300ms away from registering.

Prerender and sitemap follow the split: entry-server pulls the marketing
page map from '@pro/pages/marketing' behind a VITE_PRO_BUILD-gated dynamic
import (the proven main.tsx pattern, with an OSS stub for tsc), and
generate-sitemap lists only served routes in OSS builds (2 URLs) while
pro builds stay byte-identical — verified against a pre-migration
baseline: sitemap (37 URLs) and prerendered /, /about, /docs,
/arduino-simulator, /esp32-simulator, /v3 all identical modulo hashed
asset names. OSS prerender drops exactly the 32 marketing pages (348→316).

The OSS header slims down to match: Editor, Examples, GitHub, Discord —
the marketing links only render in pro builds, where their routes exist.
The editor Help menu links those pages absolutely (velxio.dev) in OSS,
exactly like the desktop app's Help menu.
2026-07-30 17:50:14 +02:00
David Montero 07a0bfef6e seo: emit trailing-slash canonical + sitemap URLs
Static/docs/example routes are served as <route>/index.html and nginx
301-redirects the slash-less form to add the trailing slash. The sitemap
generator, the prerender canonical/og:url, and the client useSEO canonical
all emitted the slash-LESS form, so every sitemap URL was fetched as a
redirect (filed under 'Page with redirect' in Search Console) and each
canonical pointed at a redirecting URL.

Align all three to the trailing-slash form so sitemap URL == canonical ==
served URL == 200, with no redirect hop.

- generate-sitemap.mjs: append '/' to every <loc> (root stays '/')
- prerender-seo.mjs: withSlash() on canonical + og:url (routes + examples)
- useSEO.ts: withTrailingSlash() on canonical + og:url (covers dynamic
  project pages too)
2026-06-15 06:10:32 +02:00
David Montero Crespo 12343075d8 feat: add example detail pages and SEO improvements
- Implemented ExampleDetailPage for individual example projects with SEO metadata.
- Updated routing to use ExampleDetailPage instead of ExampleLoaderPage.
- Enhanced sitemap generation to include example project URLs.
- Added prerendering support for example detail pages in the server entry.
- Improved SEO handling in ProjectByIdPage to dynamically set metadata based on project visibility.
- Refactored example ID extraction from examples.ts for sitemap generation.
- Updated console logs to reflect total URLs generated in sitemap.
2026-04-13 15:22:08 -03:00
David Montero Crespo 005f50262f feat: enhance build scripts and add SEO prerendering; improve touch interactions for wire creation 2026-03-25 00:08:46 -03:00