From b4365ec877eb68b2a0753974baeb589d21a83810 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Mon, 23 Mar 2026 18:52:35 -0300 Subject: [PATCH 1/3] feat: implement sitemap generation and search engine pinging in build process --- .github/workflows/docker-publish.yml | 6 +++ frontend/package.json | 5 ++- frontend/public/sitemap.xml | 34 +--------------- frontend/src/seoRoutes.ts | 59 ++++++++++++++++++++++++++++ scripts/generate-sitemap.ts | 59 ++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 35 deletions(-) create mode 100644 frontend/src/seoRoutes.ts create mode 100644 scripts/generate-sitemap.ts diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 1b3a7cc..945e762 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -56,6 +56,12 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max + - name: Ping search engines with sitemap + if: success() + run: | + curl -s "https://www.google.com/ping?sitemap=https%3A%2F%2Fvelxio.dev%2Fsitemap.xml" -o /dev/null -w "Google ping: %{http_code}\n" + curl -s "https://www.bing.com/ping?sitemap=https%3A%2F%2Fvelxio.dev%2Fsitemap.xml" -o /dev/null -w "Bing ping: %{http_code}\n" + - name: Update Docker Hub description uses: peter-evans/dockerhub-description@v4 with: diff --git a/frontend/package.json b/frontend/package.json index 3add610..849420d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,9 +8,10 @@ "generate:metadata": "cd .. && npx tsx scripts/generate-component-metadata.ts", "generate:favicons": "node ../scripts/generate-favicons.mjs", "generate:og-image": "node ../scripts/generate-og-image.mjs", + "generate:sitemap": "cd .. && npx tsx scripts/generate-sitemap.ts", "dev": "npm run generate:metadata && vite", - "build": "npm run generate:metadata && tsc -b && vite build", - "build:docker": "vite build", + "build": "npm run generate:metadata && npm run generate:sitemap && tsc -b && vite build", + "build:docker": "npm run generate:sitemap && vite build", "lint": "eslint .", "preview": "vite preview", "test": "vitest run", diff --git a/frontend/public/sitemap.xml b/frontend/public/sitemap.xml index 8448192..03c1201 100644 --- a/frontend/public/sitemap.xml +++ b/frontend/public/sitemap.xml @@ -2,192 +2,162 @@ - https://velxio.dev/ 2026-03-23 weekly - 1.0 + 1 - https://velxio.dev/editor 2026-03-23 weekly 0.9 - https://velxio.dev/examples 2026-03-23 weekly 0.8 - - https://velxio.dev/docs 2026-03-23 monthly 0.8 - https://velxio.dev/docs/intro 2026-03-23 monthly 0.8 - https://velxio.dev/docs/getting-started 2026-03-23 monthly 0.8 - https://velxio.dev/docs/emulator 2026-03-23 monthly 0.7 - https://velxio.dev/docs/esp32-emulation 2026-03-23 monthly 0.7 - https://velxio.dev/docs/riscv-emulation 2026-03-23 monthly 0.7 - https://velxio.dev/docs/rp2040-emulation 2026-03-23 monthly 0.7 - https://velxio.dev/docs/raspberry-pi3-emulation 2026-03-23 monthly 0.7 - https://velxio.dev/docs/components 2026-03-23 monthly 0.7 - https://velxio.dev/docs/architecture 2026-03-23 monthly 0.7 - https://velxio.dev/docs/wokwi-libs 2026-03-23 monthly 0.7 - https://velxio.dev/docs/mcp 2026-03-23 monthly 0.7 - https://velxio.dev/docs/setup 2026-03-23 monthly 0.6 - https://velxio.dev/docs/roadmap 2026-03-23 monthly 0.6 - - https://velxio.dev/arduino-simulator 2026-03-23 monthly 0.9 - https://velxio.dev/arduino-emulator 2026-03-23 monthly 0.9 - https://velxio.dev/atmega328p-simulator 2026-03-23 monthly 0.85 - https://velxio.dev/arduino-mega-simulator 2026-03-23 monthly 0.85 - https://velxio.dev/esp32-simulator 2026-03-23 monthly 0.9 - https://velxio.dev/esp32-s3-simulator 2026-03-23 monthly 0.85 - https://velxio.dev/esp32-c3-simulator 2026-03-23 monthly 0.85 - https://velxio.dev/raspberry-pi-pico-simulator 2026-03-23 monthly 0.9 - https://velxio.dev/raspberry-pi-simulator 2026-03-23 monthly 0.85 - - https://velxio.dev/v2 2026-03-23 @@ -195,6 +165,4 @@ 0.9 - - diff --git a/frontend/src/seoRoutes.ts b/frontend/src/seoRoutes.ts new file mode 100644 index 0000000..42d282a --- /dev/null +++ b/frontend/src/seoRoutes.ts @@ -0,0 +1,59 @@ +/** + * Single source of truth for all public, indexable routes. + * Used by: + * 1. scripts/generate-sitemap.ts → builds sitemap.xml at build time + * 2. Any component that needs the canonical URL list + * + * Routes with `noindex: true` are excluded from the sitemap. + */ + +export interface SeoRoute { + path: string; + /** 0.0 – 1.0 (default 0.5) */ + priority?: number; + changefreq?: 'daily' | 'weekly' | 'monthly' | 'yearly'; + /** If true, excluded from sitemap */ + noindex?: boolean; +} + +export const SEO_ROUTES: SeoRoute[] = [ + // ── Main pages + { path: '/', priority: 1.0, changefreq: 'weekly' }, + { path: '/editor', priority: 0.9, changefreq: 'weekly' }, + { path: '/examples', priority: 0.8, changefreq: 'weekly' }, + + // ── Documentation + { path: '/docs', priority: 0.8, changefreq: 'monthly' }, + { path: '/docs/intro', priority: 0.8, changefreq: 'monthly' }, + { path: '/docs/getting-started', priority: 0.8, changefreq: 'monthly' }, + { path: '/docs/emulator', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/esp32-emulation', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/riscv-emulation', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/rp2040-emulation', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/raspberry-pi3-emulation', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/components', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/architecture', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/wokwi-libs', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/mcp', priority: 0.7, changefreq: 'monthly' }, + { path: '/docs/setup', priority: 0.6, changefreq: 'monthly' }, + { path: '/docs/roadmap', priority: 0.6, changefreq: 'monthly' }, + + // ── SEO keyword landing pages + { path: '/arduino-simulator', priority: 0.9, changefreq: 'monthly' }, + { path: '/arduino-emulator', priority: 0.9, changefreq: 'monthly' }, + { path: '/atmega328p-simulator', priority: 0.85, changefreq: 'monthly' }, + { path: '/arduino-mega-simulator', priority: 0.85, changefreq: 'monthly' }, + { path: '/esp32-simulator', priority: 0.9, changefreq: 'monthly' }, + { path: '/esp32-s3-simulator', priority: 0.85, changefreq: 'monthly' }, + { path: '/esp32-c3-simulator', priority: 0.85, changefreq: 'monthly' }, + { path: '/raspberry-pi-pico-simulator', priority: 0.9, changefreq: 'monthly' }, + { path: '/raspberry-pi-simulator', priority: 0.85, changefreq: 'monthly' }, + + // ── Release pages + { path: '/v2', priority: 0.9, changefreq: 'monthly' }, + + // ── Auth / admin (noindex) + { path: '/login', noindex: true }, + { path: '/register', noindex: true }, + { path: '/admin', noindex: true }, +]; diff --git a/scripts/generate-sitemap.ts b/scripts/generate-sitemap.ts new file mode 100644 index 0000000..3c7c6c1 --- /dev/null +++ b/scripts/generate-sitemap.ts @@ -0,0 +1,59 @@ +/** + * Auto-generates frontend/public/sitemap.xml from seoRoutes.ts + * Run: npx tsx scripts/generate-sitemap.ts + * Integrated into: npm run build (via generate:sitemap) + */ + +import { writeFileSync } from 'fs'; +import { resolve } from 'path'; + +// Import the single source of truth +import { SEO_ROUTES } from '../frontend/src/seoRoutes'; + +const DOMAIN = 'https://velxio.dev'; +const TODAY = new Date().toISOString().slice(0, 10); // YYYY-MM-DD + +const indexableRoutes = SEO_ROUTES.filter((r) => !r.noindex); + +const xml = ` + +${indexableRoutes + .map( + (r) => ` + + ${DOMAIN}${r.path} + ${TODAY} + ${r.changefreq ?? 'monthly'} + ${r.priority ?? 0.5} + ` + ) + .join('')} + + +`; + +const outPath = resolve(__dirname, '../frontend/public/sitemap.xml'); +writeFileSync(outPath, xml.trimStart(), 'utf-8'); +console.log(`sitemap.xml generated → ${indexableRoutes.length} URLs (${TODAY})`); + +// Also ping Google & Bing sitemap endpoints (non-blocking, best-effort) +const SITEMAP_URL = `${DOMAIN}/sitemap.xml`; +const PING_URLS = [ + `https://www.google.com/ping?sitemap=${encodeURIComponent(SITEMAP_URL)}`, + `https://www.bing.com/ping?sitemap=${encodeURIComponent(SITEMAP_URL)}`, +]; + +if (process.argv.includes('--ping')) { + console.log('Pinging search engines...'); + Promise.allSettled( + PING_URLS.map(async (url) => { + try { + const res = await fetch(url); + console.log(` ${res.ok ? 'OK' : 'FAIL'} ${url.split('?')[0]}`); + } catch (e: any) { + console.log(` FAIL ${url.split('?')[0]}: ${e.message}`); + } + }) + ); +} From 5fdeb7fc646fc3087f9de279de49aeef5faed836 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Mon, 23 Mar 2026 18:54:02 -0300 Subject: [PATCH 2/3] feat: update Velxio 2.0 landing page descriptions for clarity and SEO optimization; mark subprojects as dirty --- frontend/src/pages/Velxio2Page.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/Velxio2Page.tsx b/frontend/src/pages/Velxio2Page.tsx index 24dfb5f..be37d62 100644 --- a/frontend/src/pages/Velxio2Page.tsx +++ b/frontend/src/pages/Velxio2Page.tsx @@ -118,7 +118,7 @@ const JSON_LD: object[] = [ operatingSystem: 'Any (browser-based)', softwareVersion: '2.0.0', description: - 'Velxio 2.0 — a free, open-source multi-board embedded systems simulator. 19 boards, 5 CPU architectures, QEMU-based ESP32 emulation, sensor simulation, 68+ examples. Runs in your browser.', + 'Velxio 2.0 — simulate Arduino, ESP32, Raspberry Pi Pico, and Raspberry Pi 3 in your browser. 19 boards, 68+ examples, realistic sensor simulation. Free and open-source.', url: 'https://velxio.dev/v2', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' }, author: { '@type': 'Person', name: 'David Montero Crespo' }, @@ -236,7 +236,7 @@ export const Velxio2Page: React.FC = () => { useSEO({ title: 'Velxio 2.0 — Multi-Board Embedded Simulator | ESP32, Raspberry Pi, Arduino, RISC-V', description: - 'Velxio 2.0 is here. 19 boards, 5 CPU architectures, QEMU-based ESP32 emulation, realistic sensor simulation, 68+ examples. A free, open-source multi-platform embedded systems simulator.', + 'Velxio 2.0 is here. Simulate Arduino, ESP32, Raspberry Pi Pico, and Raspberry Pi 3 in your browser. 19 boards, 68+ examples, realistic sensor simulation. Free and open-source.', url: 'https://velxio.dev/v2', jsonLd: JSON_LD, }); @@ -255,9 +255,9 @@ export const Velxio2Page: React.FC = () => { Multi-Platform Embedded Simulator

- 19 boards across 5 CPU architectures — AVR8, RP2040, RISC-V, Xtensa, and ARM Linux. - QEMU-based ESP32 emulation, realistic sensor simulation, 68+ ready-to-run examples. - Free, open-source, runs in your browser. + Simulate Arduino, ESP32, Raspberry Pi Pico, and Raspberry Pi 3 in your browser. + 19 boards, 68+ ready-to-run examples, realistic sensor simulation. + Free, open-source, no install needed.

From 3e77c1a546587ced3a23a1f602bbcb8d492ae06e Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Mon, 23 Mar 2026 18:56:00 -0300 Subject: [PATCH 3/3] feat: add open-source library showcase to Velxio 2.0 landing page and mark subprojects as dirty --- frontend/src/pages/Velxio2Page.css | 58 ++++++++++++++++++++++++++ frontend/src/pages/Velxio2Page.tsx | 66 ++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/frontend/src/pages/Velxio2Page.css b/frontend/src/pages/Velxio2Page.css index fca0133..6c8c80b 100644 --- a/frontend/src/pages/Velxio2Page.css +++ b/frontend/src/pages/Velxio2Page.css @@ -233,6 +233,64 @@ background: #484848; } +/* ── Repository cards ────────────────────────────────── */ +.v2-repos { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 10px; +} + +.v2-repo-card { + display: flex; + align-items: flex-start; + gap: 12px; + background: #121214; + border: 1px solid #1c1c1e; + border-radius: 10px; + padding: 1rem 1.15rem; + text-decoration: none; + transition: border-color 0.2s, transform 0.15s; +} + +.v2-repo-card:hover { + border-color: #333; + transform: translateY(-1px); +} + +.v2-repo-card > svg { + flex-shrink: 0; + margin-top: 2px; + color: #8b949e; + fill: #8b949e; +} + +.v2-repo-card h3 { + font-size: 0.85rem; + font-weight: 600; + color: #e6edf3; + margin: 0 0 3px; +} + +.v2-repo-card p { + font-size: 0.78rem; + color: #8b949e; + margin: 0; + line-height: 1.5; +} + +.v2-repo-card--primary { + border-color: rgba(0, 122, 204, 0.3); + background: rgba(0, 122, 204, 0.06); +} + +.v2-repo-card--primary:hover { + border-color: #007acc; +} + +.v2-repo-card--primary h3 { + color: #007acc; +} + /* ── Bottom community ────────────────────────────────── */ .v2-bottom-community { display: flex; diff --git a/frontend/src/pages/Velxio2Page.tsx b/frontend/src/pages/Velxio2Page.tsx index be37d62..3cf416b 100644 --- a/frontend/src/pages/Velxio2Page.tsx +++ b/frontend/src/pages/Velxio2Page.tsx @@ -479,6 +479,72 @@ export const Velxio2Page: React.FC = () => {
+ {/* ── Open-source libraries ── */} +
+

Built on open-source

+

+ Velxio is powered by these open-source projects. Without them, none of this would be possible. +

+
+ + +
+

avr8js

+

AVR8 CPU emulator in JavaScript — powers Arduino Uno, Nano, Mega simulation

+
+
+ + +
+

rp2040js

+

RP2040 emulator — powers Raspberry Pi Pico and Pico W simulation

+
+
+ + +
+

wokwi-elements

+

Web Components for electronic parts — LEDs, buttons, sensors, displays, and more

+
+
+ + +
+

wokwi-boards

+

SVG board definitions for Arduino, ESP32, Raspberry Pi Pico, and other boards

+
+
+ + +
+

QEMU (lcgamboa fork)

+

QEMU fork with ESP32 Xtensa LX6/LX7 emulation support

+
+
+ + +
+

QEMU (Espressif)

+

Official Espressif QEMU fork for ESP32 development and testing

+
+
+ + +
+

wokwi-features

+

Feature tracking and component specifications for the Wokwi ecosystem

+
+
+ + +
+

Velxio

+

This project — free, open-source multi-board embedded simulator

+
+
+
+
+ {/* ── Bottom CTA ── */}

Try Velxio 2.0 now