Astro static site, FR/EN path-based i18n, light/dark theming, hub linking to CVE Watch and Convert services.
6.3 KiB
Ombrora Hub Landing Page — Design
Purpose
A landing page at www.ombrora.com acting as a hub linking to Ombrora's existing services:
- CVE Watch — a CVE-tracking blog, published in French (
cve-fr.ombrora.com) and English (cve-en.ombrora.com) as two locale-specific deployments of the same underlying service. - Convert (
convert.ombrora.com) — a file conversion tool (documents, audio, images, video, archives).
More services will be added to the hub over time; the design must make that cheap.
Requirements
- Built with Astro, static output only (no SSR/SSR adapter) — required for SEO and for hosting on static shared hosting.
- Multilingual: French and English, via path-based routing (
/en/,/fr/), symmetric (no unprefixed default locale route). - Deployed to o2switch shared hosting: plain HTML/CSS/JS output uploaded to the host, no server-side runtime,
.htaccessavailable for Apache-level rules. - SEO-optimized: prerendered HTML, meta tags, hreflang, sitemap, robots.txt.
- Supports light and dark mode.
- No existing brand assets — visual direction is proposed as part of this design.
- Scope is minimal: hero + service cards + footer. No About/Contact/legal pages, no analytics.
Tech stack & project structure
- Astro (latest stable),
output: 'static'(Astro's default — no adapter needed). - No UI framework — plain Astro components and CSS are sufficient for this scope.
- npm as package manager.
src/
components/ Header.astro, Footer.astro, ServiceCard.astro, LanguageSwitcher.astro, ThemeToggle.astro
i18n/ en.ts, fr.ts (UI strings), services.ts (service list, per-locale copy)
layouts/ BaseLayout.astro (head/meta/hreflang/OG tags, theme init script)
pages/
en/index.astro
fr/index.astro
public/
.htaccess (root language redirect)
robots.txt
astro.config.mjs (i18n config, sitemap integration)
Routing & i18n
astro.config.mjs:
i18n: {
locales: ['en', 'fr'],
defaultLocale: 'en',
routing: { prefixDefaultLocale: true }
}
This produces symmetric /en/ and /fr/ routes (no bare unprefixed locale route). Astro's astro:i18n helpers (e.g. getRelativeLocaleUrl) generate cross-locale links for the language switcher and hreflang tags.
public/.htaccess handles the bare www.ombrora.com/ root with a real server-side redirect based on the Accept-Language header:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{HTTP:Accept-Language} fr [NC]
RewriteRule ^$ /fr/ [R=302,L]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^$ /en/ [R=302,L]
French-preferring browsers land on /fr/; everything else defaults to /en/. No JavaScript redirect needed.
Content model
src/i18n/services.ts is the single source of truth for the service cards. url may be a plain string (same URL regardless of locale) or a { en, fr } object (locale-specific URL) — ServiceCard.astro resolves whichever shape is present against the current locale. Adding a future service, whether single-domain or per-locale-domain, means adding one entry here.
export const services = [
{
id: 'cve',
url: { en: 'https://cve-en.ombrora.com', fr: 'https://cve-fr.ombrora.com' },
name: { en: 'CVE Watch', fr: 'Veille CVE' },
description: { en: '...', fr: '...' },
},
{
id: 'convert',
url: 'https://convert.ombrora.com',
name: { en: 'Convert', fr: 'Convert' },
description: { en: '...', fr: '...' },
},
]
Note: CVE Watch is one logical service with two locale-specific deployments (matching the existing cve-fr/cve-en split), rendered as a single card whose link target depends on the hub's current locale — not two separate cards.
src/i18n/en.ts / fr.ts hold flat key-value UI strings (hero title/subtitle, nav labels, footer text), looked up directly in templates (e.g. t.hero.title) — no i18n library needed for this scope.
Pages & components
- BaseLayout.astro:
<html lang>, meta description, canonical URL, hreflang alternates (en, fr, x-default → en), Open Graph/Twitter card tags, favicon, global CSS, and the pre-paint theme-init script (see Theming). - Header.astro: Ombrora wordmark, LanguageSwitcher (links to the equivalent page in the other locale, not just the other locale's root), ThemeToggle.
- Hero: short tagline introducing Ombrora as a hub for security and utility tools.
- ServiceCard.astro × 2: name, one-line description, a tag (e.g. "CVE Blog", "File Converter"), outbound link resolved per current locale.
- Footer.astro: copyright, optional contact mailto. No legal/About pages in this scope.
Visual direction
Dark, technical aesthetic fitting a security/CVE tracker and dev utility tool: neutral dark/light backgrounds, one accent color (cool cyan or violet) for links and highlights, a clean sans-serif for body text with a monospace accent for tags/labels. No decorative gimmicks.
Theming (light & dark mode)
Implemented via CSS custom properties (--bg, --fg, --accent, etc.) on :root, with [data-theme="dark"] / [data-theme="light"] overrides.
- Default: follows system preference (
prefers-color-scheme), applied by an inline<script>inBaseLayoutthat runs before first paint (avoids flash of wrong theme) and setsdata-themeon<html>. - Manual override: a toggle button in the Header flips
data-themeand persists the choice tolocalStorage; on later visits the stored preference takes precedence over system preference. - No extra dependency — CSS variables plus a small vanilla script.
SEO
@astrojs/sitemapintegration generating a sitemap covering both locale routes.- Per-page
<title>, meta description, canonical URL, and hreflang alternates inBaseLayout. robots.txtallowing all crawlers, referencing the sitemap.- Semantic HTML (
<main>,<section>, correct heading hierarchy), fully prerendered — no client-side rendering of critical content.
Build & deploy
astro buildoutputs static HTML/CSS/JS todist/.- Deployment to o2switch is a manual upload of
dist/(including.htaccess, which Astro copies through frompublic/unchanged). No CI/CD pipeline in this scope.
Out of scope
- About/Contact/legal pages.
- Analytics/tracking.
- Any service beyond CVE Watch and Convert (future services are added by extending
services.ts, not by redesigning the page). - CI/CD automation for deployment.