Brave Shields (and similar blockers) block Umami only as a third-party request, so point the tracker at umami.relplay.org — a proxied CNAME to the Umami server that's first-party to relplay.org — instead of the server's own host. Same Website ID; the data endpoint follows the script host, so no other change. Privacy page updated to name the new host, and a comment in astro.config.mjs records why it's a relplay.org subdomain.
105 lines
4.8 KiB
JavaScript
105 lines
4.8 KiB
JavaScript
// @ts-check
|
|
import { defineConfig } from 'astro/config';
|
|
import starlight from '@astrojs/starlight';
|
|
|
|
import tailwindcss from '@tailwindcss/vite';
|
|
|
|
// Custom highlight grammar for the playground's simple-mode command language
|
|
// (advanced-mode examples use the built-in `sql` grammar). Fence with ```rdbms.
|
|
import rdbmsLang, { rdbmsSyntax } from './src/grammars/rdbms.mjs';
|
|
|
|
// https://astro.build/config
|
|
export default defineConfig({
|
|
// Production origin (apex domain). Enables the sitemap, canonical URLs, and
|
|
// Open Graph `og:url`/`og:image` resolution. A `www` host, if used, should
|
|
// 301-redirect here so a single canonical origin is advertised. Local dev is
|
|
// unaffected — this only changes *generated absolute* URLs, not where the
|
|
// dev/preview server binds.
|
|
site: 'https://relplay.org',
|
|
// Bind the dev/preview server to IPv4 loopback. Astro/Vite's default
|
|
// `localhost` bind resolves to IPv6 `::1` here, which breaks SSH
|
|
// `-L 4321:127.0.0.1:4321` tunnels (they target IPv4). Pinning 127.0.0.1
|
|
// keeps loopback-only access and makes tunnelling unambiguous.
|
|
server: { host: '127.0.0.1' },
|
|
integrations: [
|
|
starlight({
|
|
title: 'RDBMS Playground',
|
|
tagline: 'Learn relational databases by doing.',
|
|
// Header logo: a database-table glyph with a teal primary-key cell.
|
|
// Separate light/dark files so the outline adapts to the theme;
|
|
// `replacesTitle: false` keeps the "RDBMS Playground" wordmark beside it.
|
|
logo: {
|
|
light: './src/assets/relplay-logo-light.svg',
|
|
dark: './src/assets/relplay-logo-dark.svg',
|
|
replacesTitle: false,
|
|
},
|
|
// Footer override: Starlight's default footer + a small company/source line.
|
|
components: {
|
|
Footer: './src/components/Footer.astro',
|
|
},
|
|
// TODO(Phase B): a header social link to the repo is deliberately omitted
|
|
// — the source/issues link lives understated in the footer instead.
|
|
customCss: ['./src/styles/global.css'],
|
|
// Open Graph / Twitter social card. Starlight emits og:title/url/type
|
|
// from `site`, but not an image, so add a single site-wide card.
|
|
// Source: src/assets/og-card.svg → public/og-card.png (rasterise with
|
|
// sharp; see the SVG header for the one-liner). Absolute URL required
|
|
// by scrapers — derived from the `site` origin.
|
|
head: [
|
|
{ tag: 'meta', attrs: { property: 'og:image', content: 'https://relplay.org/og-card.png' } },
|
|
{ tag: 'meta', attrs: { property: 'og:image:width', content: '1200' } },
|
|
{ tag: 'meta', attrs: { property: 'og:image:height', content: '630' } },
|
|
{
|
|
tag: 'meta',
|
|
attrs: {
|
|
property: 'og:image:alt',
|
|
content: 'RDBMS Playground — learn relational databases by doing.',
|
|
},
|
|
},
|
|
{ tag: 'meta', attrs: { name: 'twitter:card', content: 'summary_large_image' } },
|
|
{ tag: 'meta', attrs: { name: 'twitter:image', content: 'https://relplay.org/og-card.png' } },
|
|
// Privacy-friendly, cookieless analytics (self-hosted Umami). The
|
|
// Website ID is public by design (it ships in every page). The script
|
|
// loads from the Umami host, which also becomes the data destination,
|
|
// so no `data-host-url` is needed.
|
|
// - Served first-party under `umami.relplay.org` (a proxied CNAME to
|
|
// the Umami server) rather than the server's own host: privacy
|
|
// blockers (e.g. Brave Shields) block Umami only as a *third-party*
|
|
// request, so a same-registrable-domain host is not flagged.
|
|
// - data-domains: only run on the production apex, so the
|
|
// `website.relplay.pages.dev` preview and `staging.relplay.org`
|
|
// don't pollute the stats.
|
|
// - data-do-not-track: honour the browser's Do-Not-Track signal
|
|
// (those visits are not counted at all). See /privacy.
|
|
{
|
|
tag: 'script',
|
|
attrs: {
|
|
defer: true,
|
|
src: 'https://umami.relplay.org/script.js',
|
|
'data-website-id': 'fd77cfa5-cffe-4fc8-addb-1c6d7b6d9939',
|
|
'data-domains': 'relplay.org',
|
|
'data-do-not-track': true,
|
|
},
|
|
},
|
|
],
|
|
// Register the simple-mode command grammar with Expressive Code (Shiki).
|
|
expressiveCode: { shiki: { langs: [rdbmsLang, rdbmsSyntax] } },
|
|
// Pragmatic structure (ADR-website-001 §7 / website/STYLE.md): Getting
|
|
// started, Guides, Reference, Concepts. Autogenerated per directory;
|
|
// in-section order is controlled by each page's `sidebar.order`
|
|
// frontmatter.
|
|
sidebar: [
|
|
{ label: 'Getting started', items: [{ autogenerate: { directory: 'getting-started' } }] },
|
|
{ label: 'Using the playground', items: [{ autogenerate: { directory: 'using-the-playground' } }] },
|
|
{ label: 'Guides', items: [{ autogenerate: { directory: 'guides' } }] },
|
|
{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] },
|
|
{ label: 'Concepts', items: [{ autogenerate: { directory: 'concepts' } }] },
|
|
],
|
|
}),
|
|
],
|
|
|
|
vite: {
|
|
plugins: [tailwindcss()],
|
|
},
|
|
});
|