From a68b8bd33df7d956bd79ba14d8eeecb42e241d64 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 12 Jul 2026 22:29:36 +0000 Subject: [PATCH 1/2] chore: add GitHub Pages deployment workflow Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_015kFBiAzFDdHPc5j66PAw6H --- .github/workflows/ci.yml | 32 +++++++++++++++++ .github/workflows/deploy-pages.yml | 58 ++++++++++++++++++++++++++++++ README.md | 17 +++++++++ 3 files changed, 107 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/deploy-pages.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..72d4be0 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,32 @@ +name: CI + +# Build-Check für Pull Requests. Deployt niemals – das übernimmt +# ausschließlich deploy-pages.yml bei Push auf main oder manuellem Start. +on: + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Type/Astro check + run: npm run check + + - name: Build + run: npm run build diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml new file mode 100644 index 0000000..05f8696 --- /dev/null +++ b/.github/workflows/deploy-pages.yml @@ -0,0 +1,58 @@ +name: Deploy to GitHub Pages + +on: + push: + branches: [main] + workflow_dispatch: + +# Minimale Berechtigungen für das OIDC-basierte Pages-Deployment. +permissions: + contents: read + pages: write + id-token: write + +# Nur ein Pages-Deployment gleichzeitig; laufende Deployments nicht abbrechen. +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Type/Astro check + run: npm run check + + - name: Build + run: npm run build + + - name: Configure Pages + uses: actions/configure-pages@v5 + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v4 + with: + path: ./dist + + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index 423f300..e8fb3ac 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,23 @@ App-Repository [TimInTech/blitztext-linux](https://github.com/TimInTech/blitztex - `public/screenshots/` ← `docs/screenshots/linux/` (Dateinamen für das Web vereinheitlicht) - `public/images/og-*.png` ← `docs/screenshots/linux/Banner-{de,en}.png` +## Deployment (geplant) + +Als Hosting-Weg ist **GitHub Pages** vorgesehen (Deployment über GitHub +Actions, Workflow: `.github/workflows/deploy-pages.yml`). Der Produktionsbuild +landet in **`dist/`** und wird von dort als Pages-Artefakt veröffentlicht. + +- **Custom Domain:** `blitztext.timintech.de` +- **DNS-Ziel (später):** `CNAME blitztext → timintech.github.io` +- Das **Repository bleibt privat**. GitHub Pages aus einem privaten Repository + benötigt einen passenden **GitHub-Tarif** (z. B. GitHub Pro / Team / + Enterprise); mit einem kostenlosen Plan ist Pages nur für öffentliche Repos + verfügbar. +- **DNS-Konfiguration und die Aktivierung von GitHub Pages sind nicht Teil + dieses Auftrags** und müssen manuell in GitHub bzw. beim DNS-Anbieter erfolgen. +- Die rechtlichen **`[PLATZHALTER]`** in Impressum und Datenschutzerklärung + müssen vor der Veröffentlichung ausgefüllt werden. + ## Noch offen vor dem öffentlichen Deployment - **Rechtliche Angaben:** Impressum und Datenschutzerklärung enthalten deutlich From c8f6a523b9e7353a1ddd99735761095159873996 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Jul 2026 06:54:32 +0000 Subject: [PATCH 2/2] fix: deploy site under GitHub Pages project path Serve the site as a GitHub Pages project page at https://timintech.github.io/blitztextweb/ instead of a custom domain. - astro.config: site=timintech.github.io, base=/blitztextweb - central withBase() helper (src/utils/base.ts) for all internal links/assets - prefix canonical, hreflang, OG, sitemap, favicon, nav, footer, images - remove custom-domain / DNS / CNAME references (README, robots, meta) - privacy pages: name GitHub Pages / GitHub, Inc. as host with official refs - workflow: scope pages:write / id-token:write to the deploy job only, workflow and build run with contents:read Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Rhz1aNuLb6REABNLkPSKNz --- .github/workflows/deploy-pages.yml | 10 +++-- README.md | 61 ++++++++++++++++-------------- astro.config.mjs | 7 +++- package.json | 2 +- public/robots.txt | 2 +- src/components/Footer.astro | 13 ++++--- src/components/Header.astro | 7 ++-- src/components/Landing.astro | 9 +++-- src/data/product.ts | 4 +- src/layouts/Base.astro | 19 ++++++---- src/pages/404.astro | 5 ++- src/pages/datenschutz.astro | 36 ++++++++++-------- src/pages/en/privacy.astro | 35 +++++++++-------- src/utils/base.ts | 16 ++++++++ 14 files changed, 136 insertions(+), 90 deletions(-) create mode 100644 src/utils/base.ts diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 05f8696..a4da792 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -5,11 +5,11 @@ on: branches: [main] workflow_dispatch: -# Minimale Berechtigungen für das OIDC-basierte Pages-Deployment. +# Workflow-weit nur Leserechte. Die für das OIDC-basierte Pages-Deployment +# nötigen Schreibrechte (pages/id-token) sind ausschließlich dem deploy-Job +# zugeordnet, damit der build-Job sie nicht erbt. permissions: contents: read - pages: write - id-token: write # Nur ein Pages-Deployment gleichzeitig; laufende Deployments nicht abbrechen. concurrency: @@ -49,6 +49,10 @@ jobs: deploy: needs: build runs-on: ubuntu-latest + # Nur der Deploy-Job erhält die für actions/deploy-pages nötigen Rechte. + permissions: + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} diff --git a/README.md b/README.md index e8fb3ac..90ba235 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # blitztextweb -Statische Produktwebsite für [Blitztext Linux](https://github.com/TimInTech/blitztext-linux) – -vorgesehen für die Domain `https://blitztext.timintech.de`. +Statische Produktwebsite für [Blitztext Linux](https://github.com/TimInTech/blitztext-linux), +veröffentlicht über GitHub Pages unter `https://timintech.github.io/blitztextweb/`. Dieses Repository enthält **ausschließlich die Website**. Die Desktop-App lebt im getrennten Repository [TimInTech/blitztext-linux](https://github.com/TimInTech/blitztext-linux). @@ -29,19 +29,22 @@ npm run build # Produktionsbuild → dist/ npm run preview # gebauten Stand lokal ansehen ``` -Der Produktionsbuild landet im Ordner **`dist/`** und ist für das Hosting am -Domain-Root (`/`) gebaut. +Der Produktionsbuild landet im Ordner **`dist/`** und ist für die Auslieferung +unter dem GitHub-Pages-Unterpfad **`/blitztextweb/`** gebaut +(`base: '/blitztextweb'` in `astro.config.mjs`). ## Seiten +Alle Routen werden unter dem Unterpfad `/blitztextweb/` ausgeliefert. + | Route | Inhalt | | :--- | :--- | -| `/` | Deutsche Startseite | -| `/en/` | Englische Startseite | -| `/impressum/` | Impressum (Vorlage mit markierten Platzhaltern) | -| `/datenschutz/` | Datenschutzerklärung (Deutsch) | -| `/en/privacy/` | Datenschutzerklärung (Englisch) | -| `/404.html` | Fehlerseite | +| `/blitztextweb/` | Deutsche Startseite | +| `/blitztextweb/en/` | Englische Startseite | +| `/blitztextweb/impressum/` | Impressum (Vorlage mit markierten Platzhaltern) | +| `/blitztextweb/datenschutz/` | Datenschutzerklärung (Deutsch) | +| `/blitztextweb/en/privacy/` | Datenschutzerklärung (Englisch) | +| `/blitztextweb/404.html` | Fehlerseite | ## Herkunft der Blitztext-Assets @@ -54,26 +57,28 @@ App-Repository [TimInTech/blitztext-linux](https://github.com/TimInTech/blitztex - `public/screenshots/` ← `docs/screenshots/linux/` (Dateinamen für das Web vereinheitlicht) - `public/images/og-*.png` ← `docs/screenshots/linux/Banner-{de,en}.png` -## Deployment (geplant) +## Deployment + +Gehostet wird **ausschließlich über GitHub Pages** (Project Page) unter: + +`https://timintech.github.io/blitztextweb/` -Als Hosting-Weg ist **GitHub Pages** vorgesehen (Deployment über GitHub -Actions, Workflow: `.github/workflows/deploy-pages.yml`). Der Produktionsbuild -landet in **`dist/`** und wird von dort als Pages-Artefakt veröffentlicht. +Es wird **keine Custom Domain** verwendet – es gibt keine `CNAME`-Datei und +keine DNS-Konfiguration. -- **Custom Domain:** `blitztext.timintech.de` -- **DNS-Ziel (später):** `CNAME blitztext → timintech.github.io` -- Das **Repository bleibt privat**. GitHub Pages aus einem privaten Repository - benötigt einen passenden **GitHub-Tarif** (z. B. GitHub Pro / Team / - Enterprise); mit einem kostenlosen Plan ist Pages nur für öffentliche Repos - verfügbar. -- **DNS-Konfiguration und die Aktivierung von GitHub Pages sind nicht Teil - dieses Auftrags** und müssen manuell in GitHub bzw. beim DNS-Anbieter erfolgen. -- Die rechtlichen **`[PLATZHALTER]`** in Impressum und Datenschutzerklärung - müssen vor der Veröffentlichung ausgefüllt werden. +- Deployment über GitHub Actions, Workflow `.github/workflows/deploy-pages.yml` + (Trigger: Push auf `main` oder manueller `workflow_dispatch`). Der + Produktionsbuild in **`dist/`** wird als Pages-Artefakt veröffentlicht. +- Pull Requests werden nur von `.github/workflows/ci.yml` geprüft (Build ohne + Deploy) und deployen niemals. +- Die Schreibrechte `pages: write` / `id-token: write` gelten ausschließlich für + den Deploy-Job; Build und Workflow-Ebene laufen mit `contents: read`. +- Die eigentliche **Aktivierung von GitHub Pages** (Settings → Pages → Source: + *GitHub Actions*) erfolgt manuell und ist nicht Teil dieses Repos. ## Noch offen vor dem öffentlichen Deployment -- **Rechtliche Angaben:** Impressum und Datenschutzerklärung enthalten deutlich - markierte `[PLATZHALTER]` (Betreiber, Anschrift, Kontakt, Hosting-Anbieter/Logdaten). - Diese müssen vor der Veröffentlichung ausgefüllt werden. -- **Deployment und DNS** waren nicht Bestandteil des Erstellungsauftrags dieser Website. +- **Rechtliche Angaben:** Das Impressum enthält deutlich markierte + `[PLATZHALTER]` (Betreiber, Anschrift, Kontakt). Diese sind rechtlich + erforderlich (u. a. § 5 DDG) und müssen vom Betreiber ausgefüllt werden, bevor + GitHub Pages öffentlich aktiviert wird. diff --git a/astro.config.mjs b/astro.config.mjs index 97822b8..a8183e0 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -2,8 +2,11 @@ import { defineConfig } from 'astro/config'; import sitemap from '@astrojs/sitemap'; // https://astro.build/config +// Auslieferung als GitHub-Pages-Project-Page unter +// https://timintech.github.io/blitztextweb/ (Unterpfad, kein Domain-Root). export default defineConfig({ - site: 'https://blitztext.timintech.de', + site: 'https://timintech.github.io', + base: '/blitztextweb', output: 'static', trailingSlash: 'ignore', integrations: [ @@ -13,7 +16,7 @@ export default defineConfig({ }), ], build: { - // saubere /pfad/index.html-Ausgabe für statisches Hosting am Domain-Root + // saubere /pfad/index.html-Ausgabe für statisches Hosting format: 'directory', }, }); diff --git a/package.json b/package.json index f23dfc0..621528f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "blitztextweb", "version": "1.0.0", "private": true, - "description": "Static product website for Blitztext Linux (blitztext.timintech.de)", + "description": "Static product website for Blitztext Linux (https://timintech.github.io/blitztextweb/)", "type": "module", "scripts": { "dev": "astro dev", diff --git a/public/robots.txt b/public/robots.txt index 9e1b555..2239798 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,4 +1,4 @@ User-agent: * Allow: / -Sitemap: https://blitztext.timintech.de/sitemap-index.xml +Sitemap: https://timintech.github.io/blitztextweb/sitemap-index.xml diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 7467068..afec75b 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -2,14 +2,17 @@ import type { Dict } from '../i18n'; import { langPrefix, type Lang } from '../i18n'; import { product } from '../data/product'; +import { withBase } from '../utils/base'; interface Props { dict: Dict; } const { dict } = Astro.props; -const home = `${langPrefix(dict.lang as Lang)}/`; -const privacyUrl = dict.lang === 'de' ? '/datenschutz/' : '/en/privacy/'; +const home = withBase(`${langPrefix(dict.lang as Lang)}/`); +const privacyUrl = withBase(dict.lang === 'de' ? '/datenschutz/' : '/en/privacy/'); +const imprintUrl = withBase('/impressum/'); +const otherLangUrl = withBase(dict.otherLangUrl); const year = new Date().getFullYear(); --- @@ -18,7 +21,7 @@ const year = new Date().getFullYear();
- {dict.flow.imgAlt} + {dict.flow.imgAlt}
{recordingShot.caption}
@@ -149,7 +150,7 @@ const recordingShot = dict.screenshots.items[1]!; { dict.screenshots.items.map((item) => (
- {item.alt} + {item.alt}
{item.caption}
)) @@ -162,7 +163,7 @@ const recordingShot = dict.screenshots.items[1]!; { dict.screenshots.trayStates.map((state) => (
  • - {state.alt} + {state.alt} {state.label}
  • )) diff --git a/src/data/product.ts b/src/data/product.ts index 0dcf022..20acb0f 100644 --- a/src/data/product.ts +++ b/src/data/product.ts @@ -9,7 +9,9 @@ export const product = { version: '0.8.1', license: 'MIT', os: 'Linux', - siteUrl: 'https://blitztext.timintech.de', + // Origin der GitHub-Pages-Auslieferung. Der Unterpfad (`base`) wird zentral + // über `withBase` bzw. `import.meta.env.BASE_URL` ergänzt. + siteUrl: 'https://timintech.github.io', repoUrl: 'https://github.com/TimInTech/blitztext-linux', releasesUrl: 'https://github.com/TimInTech/blitztext-linux/releases', latestReleaseUrl: 'https://github.com/TimInTech/blitztext-linux/releases/tag/v0.8.1', diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index c93be7d..447f468 100644 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -1,6 +1,7 @@ --- import type { Dict } from '../i18n'; import { product } from '../data/product'; +import { withBase } from '../utils/base'; import Header from '../components/Header.astro'; import Footer from '../components/Footer.astro'; import '../styles/global.css'; @@ -29,10 +30,12 @@ const { includeAppSchema = false, } = Astro.props; -const canonical = new URL(path, product.siteUrl).href; -const altUrl = altPath !== null ? new URL(altPath, product.siteUrl).href : null; -const ogImage = new URL(dict.meta.ogImage, product.siteUrl).href; -// x-default zeigt auf die deutsche Fassung (Standardsprache der Domain) +// Alle absoluten URLs enthalten den GitHub-Pages-Unterpfad (`base`). +const canonical = new URL(withBase(path), product.siteUrl).href; +const altUrl = altPath !== null ? new URL(withBase(altPath), product.siteUrl).href : null; +const ogImage = new URL(withBase(dict.meta.ogImage), product.siteUrl).href; +const siteHome = new URL(withBase('/'), product.siteUrl).href; +// x-default zeigt auf die deutsche Fassung (Standardsprache der Website) const xDefault = dict.lang === 'de' ? canonical : altUrl; // Strukturierte Daten: ausschließlich im App-Repository bestätigte Angaben. @@ -44,7 +47,7 @@ const appSchema = { applicationCategory: 'UtilitiesApplication', softwareVersion: product.version, license: product.licenseUrl, - url: product.siteUrl, + url: siteHome, downloadUrl: product.releasesUrl, softwareHelp: product.setupDocUrl, sameAs: product.repoUrl, @@ -63,8 +66,8 @@ const appSchema = { {title} - - + + {altUrl && altLang && } @@ -92,7 +95,7 @@ const appSchema = { -
    +
    diff --git a/src/pages/404.astro b/src/pages/404.astro index 4e66506..e9ddeb8 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -1,6 +1,7 @@ --- import Base from '../layouts/Base.astro'; import { dicts } from '../i18n'; +import { withBase } from '../utils/base'; // Fehlerseite: deutschsprachig als Standard, mit klar gekennzeichnetem // englischem Absatz – statisch, ohne Weiterleitung. @@ -17,8 +18,8 @@ const description = 'Die angeforderte Seite existiert nicht. / The requested pag

    {dict.notFound.text}

    Page not found – the requested page does not exist or has been moved.

    diff --git a/src/pages/datenschutz.astro b/src/pages/datenschutz.astro index 8ce04a1..b3fb8ff 100644 --- a/src/pages/datenschutz.astro +++ b/src/pages/datenschutz.astro @@ -1,6 +1,7 @@ --- import Base from '../layouts/Base.astro'; import { dicts } from '../i18n'; +import { withBase } from '../utils/base'; const dict = dicts.de; const title = 'Datenschutzerklärung – Blitztext Linux'; @@ -21,8 +22,8 @@ const description =

    Datenschutzerklärung

    Diese Erklärung gilt ausschließlich für die Website - blitztext.timintech.de. Sie beschreibt den tatsächlichen - technischen Stand dieser statischen Seite. + timintech.github.io/blitztextweb. Sie beschreibt den + tatsächlichen technischen Stand dieser statischen Seite.

    Kurzfassung

    @@ -40,21 +41,24 @@ const description = erforderlich.

    -

    Server-Logdateien

    +

    Hosting und Server-Logdateien

    - Beim Aufruf der Website verarbeitet der Hosting-Anbieter technisch bedingt - Verbindungsdaten (z. B. IP-Adresse, Zeitpunkt des Abrufs, angeforderte Datei, - User-Agent), soweit dies für die Auslieferung der Seite und die Gewährleistung der - Systemsicherheit erforderlich ist (Art. 6 Abs. 1 lit. f DSGVO). + Diese Website wird über GitHub Pages ausgeliefert, einen Dienst der + GitHub, Inc. (88 Colin P. Kelly Jr. Street, + San Francisco, CA 94107, USA). Beim Aufruf der Website verarbeitet GitHub als + Hosting-Anbieter technisch bedingt Verbindungsdaten (z. B. IP-Adresse, Zeitpunkt + des Abrufs, angeforderte Datei, User-Agent), soweit dies für die Auslieferung der Seite + und die Gewährleistung der Systemsicherheit erforderlich ist + (Art. 6 Abs. 1 lit. f DSGVO). +

    +

    + Einzelheiten zur Datenverarbeitung durch GitHub regelt die + GitHub-Datenschutzerklärung; + Hinweise speziell zu GitHub Pages enthält die + GitHub-Pages-Dokumentation. + Zu Speicherdauer und etwaigen vertraglichen Grundlagen gelten ausschließlich die dort + von GitHub veröffentlichten Angaben.

    -
    -

    - ⚠ Platzhalter: [PLATZHALTER: Hosting-Anbieter, Speicherdauer - der Server-Logs und ggf. Auftragsverarbeitungsvertrag] – diese Angaben hängen - vom später gewählten Hoster ab und müssen vor dem öffentlichen Deployment ergänzt - werden. -

    -

    Externe Links

    @@ -80,7 +84,7 @@ const description = Nach der DSGVO stehen dir gegenüber dem Verantwortlichen u. a. Rechte auf Auskunft, Berichtigung, Löschung und Einschränkung der Verarbeitung zu, sowie ein Beschwerderecht bei einer Aufsichtsbehörde. Der Verantwortliche ist im - Impressum benannt. + Impressum benannt.

    diff --git a/src/pages/en/privacy.astro b/src/pages/en/privacy.astro index c2aee1b..44929b2 100644 --- a/src/pages/en/privacy.astro +++ b/src/pages/en/privacy.astro @@ -1,6 +1,7 @@ --- import Base from '../../layouts/Base.astro'; import { dicts } from '../../i18n'; +import { withBase } from '../../utils/base'; const dict = dicts.en; const title = 'Privacy Policy – Blitztext Linux'; @@ -21,8 +22,8 @@ const description =

    Privacy Policy

    This policy applies exclusively to the website - blitztext.timintech.de. It describes the actual technical state - of this static site. + timintech.github.io/blitztextweb. It describes the actual technical + state of this static site.

    Summary

    @@ -39,21 +40,23 @@ const description = No cookie banner is therefore required.

    -

    Server log files

    +

    Hosting and server log files

    - When you visit the website, the hosting provider technically processes connection - data (e.g. IP address, time of access, requested file, user agent) to the extent - required to deliver the page and ensure system security - (Art. 6(1)(f) GDPR). + This website is served via GitHub Pages, a service provided by + GitHub, Inc. (88 Colin P. Kelly Jr. Street, + San Francisco, CA 94107, USA). When you visit the website, GitHub as the + hosting provider technically processes connection data (e.g. IP address, time of + access, requested file, user agent) to the extent required to deliver the page and + ensure system security (Art. 6(1)(f) GDPR). +

    +

    + Details on GitHub's data processing are set out in the + GitHub Privacy Statement; + information specific to GitHub Pages is provided in the + GitHub Pages documentation. + Only the information published there by GitHub applies to retention periods and any + contractual basis.

    -
    -

    - ⚠ Placeholder: [PLACEHOLDER: hosting provider, server log - retention period, and data processing agreement if applicable] – these - details depend on the hosting provider chosen later and must be completed before - the public deployment. -

    -

    External links

    @@ -78,7 +81,7 @@ const description = Under the GDPR you have, among others, the rights to access, rectification, erasure, and restriction of processing, as well as the right to lodge a complaint with a supervisory authority. The controller is named in the - imprint (German). + imprint (German).

    diff --git a/src/utils/base.ts b/src/utils/base.ts new file mode 100644 index 0000000..151ba68 --- /dev/null +++ b/src/utils/base.ts @@ -0,0 +1,16 @@ +/** + * Zentrale Base-URL-Behandlung für die Auslieferung als GitHub-Pages- + * Project-Page unter einem Unterpfad (z. B. `/blitztextweb/`). + * + * `import.meta.env.BASE_URL` wird von Astro aus `base` in `astro.config.mjs` + * abgeleitet (hier `/blitztextweb/`). Ohne konfiguriertes `base` ist der Wert + * `/`, sodass sich `withBase` neutral verhält (Auslieferung am Domain-Root). + */ + +/** Präfixiert einen absoluten internen Pfad mit der konfigurierten Base-URL. */ +export function withBase(path: string): string { + // Externe URLs, Anker und relative Pfade bleiben unverändert. + if (!path.startsWith('/')) return path; + const base = import.meta.env.BASE_URL.replace(/\/$/, ''); + return `${base}${path}`; +}