Contact Us

Base Components

DOC-00009 reference implementor, developer

Base components are document-level utilities used by the layout shell. SEO, Analytics, and Favicon are rendered inside BaseLayout <head>. ConsentBanner is rendered in <body> after page content. SkipLink is integrated by the site header component. ConsentReset is placed by the site operator via MDX import. All files live in src/core/components/base/ and are CORE-OWNED.

Who this is for

  • Implementors creating pages that need SEO or analytics customization
  • Developers extending the document shell
  • AI agents wiring content collection routes through BaseLayout

SEO

File: src/core/components/base/SEO.astro

Emits <title>, <meta description>, <link rel="canonical">, Open Graph tags, and Twitter Card metadata. Used inside BaseLayout’s <head>.

Props

PropTypeDefaultNotes
titlestringrequiredPage title. Rendered as {title} | {siteTitle}
descriptionstringrequiredMeta description and OG description
canonicalstringauto from URL + configOverride canonical URL
noindexbooleanfalseEmits noindex,nofollow robots tag
ogImagestringsiteConfig.ogImageOG image URL or path
type'website' | 'article''website'OG type
datePublishedDateReserved for structured data output
dateModifiedDateReserved for structured data output

Behavior

  • Title format: {title} | {siteConfig.siteTitle}
  • Canonical URL: Defaults to siteConfig.siteUrl + Astro.url.pathname. Override with canonical prop for cross-posted content.
  • OG image resolution chain (PLN-23): Explicit ogImage prop → generated /og/{path}/ (for eligible routes) → siteConfig.ogImage (for non-eligible routes). Non-eligible routes are those with noindex: true. For generated OG routes, also emits og:image:type (image/png), og:image:width (1200), and og:image:height (630) meta tags. Relative paths are resolved against siteConfig.siteUrl. Absolute URLs pass through unchanged.
  • noindex: When true, emits <meta name="robots" content="noindex,nofollow" />. Also changes OG image resolution — noindex pages fall back to siteConfig.ogImage instead of the generated OG route. Use for utility pages, drafts, and internal docs.
  • Structured data: The datePublished and dateModified props are accepted for structured-data output.

Analytics

File: src/core/components/base/Analytics.astro

Consent-gated dynamic injection of Google Tag Manager, Google Analytics GA4, and custom third-party snippets. Rendered in BaseLayout’s <head>. Also provides window.trackEvent() for consent-aware event dispatch.

Injection Logic

  1. When consentRequired is false → scripts inject immediately on page load.
  2. When consentRequired is true → scripts inject only after the user accepts consent via ConsentBanner.
  3. GTM takes precedence — when both GTM and GA4 are enabled, only GTM loads.
  4. Custom snippets inject after GTM/GA4 in config array order.
  5. In dev mode, no scripts inject regardless of consent state.

For full configuration reference, see Analytics & Consent.

Favicon

File: src/core/components/base/Favicon.astro

Emits four favicon <link> tags from siteConfig.favicons. Rendered in BaseLayout’s <head>.

Output

<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />

Filenames come from siteConfig.favicons (faviconIco, faviconSvg, faviconApple, siteManifest). Place the actual files in public/.

File: src/core/components/base/SkipLink.astro

Accessibility skip-to-content link component. It is intended to render inside SiteHeader (the site navigation bar), not in BaseLayout <body>.

Behavior

  • Targets #main-content (the <main> element id in PageGridLayout).
  • Visually hidden by default using transform: translateY(-100%).
  • Becomes visible on keyboard focus with a smooth transition.
  • Uses --pt-z-skip-link (200) to layer above page content.
  • Focus state styled with --st-color-focus-ring and --pt-focus-ring-width.

No props — the component is self-contained.

ConsentBanner

File: src/core/components/base/ConsentBanner.astro

Cookie consent banner that gates analytics script loading. Renders as a fixed bottom bar with three equally-weighted buttons: Accept, Reject, and Required Only. Uses vanilla TypeScript for visibility and consent state management.

Behavior

  • Appears on first visit when consentRequired is true and at least one analytics provider or custom snippet is configured.
  • Stays hidden when consentRequired is false, when no providers are configured, or when valid (non-expired) consent exists.
  • Writes consent state to localStorage (analytics-consent key) on button click.
  • Dispatches a consent-granted CustomEvent on window when Accept is clicked, triggering the injection engine.
  • Sets data-consent-banner attribute on <html> for body padding clearance while visible.
  • Transitions respect prefers-reduced-motion.

Configuration

Banner copy, button labels, policy link, and expiration period are configured via siteConfig.analytics.consent in site.ts. See Analytics & Consent for the full field reference.

No props — the component reads all configuration from siteConfig.

ConsentReset

File: src/core/components/base/ConsentReset.astro

Consent revocation control for placement on the privacy policy page. Renders a “Reset Cookie Preferences” button that clears consent state, removes analytics cookies, and triggers a page reload.

Usage

Import and place in any MDX page where consent revocation should be available:

import ConsentReset from "@core/components/base/ConsentReset.astro";

## Manage Your Consent

<ConsentReset />

Behavior

  • Renders only when consentRequired is true (server-side gate).
  • Clears localStorage consent state, clears cookies matching cookieClearingPatterns, and reloads the page.
  • After reload, the consent banner re-appears and no analytics scripts are present.

No props — the component reads siteConfig.analytics for consent state and cookie clearing patterns.

Ownership: CORE-OWNED component, SITE-OWNED placement. The theme ships the component; the site operator places it via MDX import.

Manual accessibility test entries verified during the accessibility audit. Covers keyboard operability, screen-reader announcements, and ARIA semantics.

SkipLink

Interaction Expected Behavior WCAG Criterion Test Method
Reload the page, press Tab onceSkip link appears visually and is the first focusable element on the page2.4.1 Bypass Blocks Keyboard
Press Enter on the visible Skip linkFocus moves to the main content area; subsequent Tab presses move through main content2.4.1 Bypass Blocks Keyboard
Focus the Skip link with NVDA runningNVDA announces "Skip to main content" or similar descriptive text2.4.1 Bypass Blocks Screen Reader

ConsentBanner

Interaction Expected Behavior WCAG Criterion Test Method
Clear localStorage and reload; Tab through the banner controlsAll buttons are focusable in logical order with visible focus rings2.1.1 Keyboard Keyboard
Press Enter on the accept buttonBanner dismisses, focus moves to a logical location (not lost)2.1.1 Keyboard Keyboard
Inspect the banner container in DevToolsBanner has an appropriate role (dialog, alertdialog, or region) and an accessible name via aria-label or aria-labelledby4.1.2 Name, Role, Value Visual Inspection
Trigger banner with NVDA runningNVDA announces the banner and each button label4.1.2 Name, Role, Value Screen Reader
Dismiss the banner with prefers-reduced-motion: reduce enabledDismiss animation is suppressed or instantaneous2.3.3 Animation from Interactions Visual Inspection

ConsentReset

Interaction Expected Behavior WCAG Criterion Test Method
Tab to the ConsentReset control after consent has been acceptedControl is focusable with visible focus ring2.1.1 Keyboard Keyboard
Press Enter on the ConsentReset controlConsent state is cleared and the consent banner reappears2.1.1 Keyboard Keyboard
Focus the ConsentReset control with NVDA runningNVDA announces the control with a descriptive label4.1.2 Name, Role, Value Screen Reader
REQ-00045 normative Components shall encapsulate styling and behavior.
REQ-00046 normative Framework-free components are preferred.
REQ-00047 normative Components shall expose stable public APIs.
REQ-00082 implemented A skip-to-content link shall be provided.
REQ-00099 normative Metadata requirements shall apply to all pages.
REQ-00201 implemented The theme shall provide a complete SEO <head> system with site-level defaults from site.ts and per-page frontmatter override support, covering: <title>, <meta name="description">, <meta name="author">, Open Graph tags (og:title, og:description, og:image, og:url), and Twitter Card tags, wired into BaseLayout.astro or a dedicated SEOHead.astro component.
REQ-00202 implemented The canonical site URL shall be defined once in site.ts and used as the default for all URL-dependent outputs (sitemap, canonical tags, Open Graph metadata), with environment variables serving only as override mechanisms.

Search

Search across pages and articles. Use arrow keys to navigate results.

Search across pages and articles.

Loading search...

Search is unavailable. Please try again later.

    No results for ""

    Try different keywords or fewer words.