TenantAtlas/apps/website/src/components/Meta.astro
ahmido 2e6504618c 409: add evaluation, procurement and rollout website surface (#408)
## Summary
- add the localized evaluation-readiness route pair at `/evaluierung` and `/en/evaluation` with a shared page component
- wire homepage, platform, trust, review-pack, use-case, footer, and locale-switcher discovery paths into the new evaluation surface
- add smoke coverage plus full Spec Kit artifacts for the evaluation, procurement, and rollout readiness feature

## Validation
- `corepack pnpm --filter @tenantatlas/website build`
- `WEBSITE_PORT=4322 corepack pnpm --filter @tenantatlas/website test tests/smoke/public-routes.spec.ts`
- `WEBSITE_PORT=4323 corepack pnpm --filter @tenantatlas/website test tests/smoke/interaction.spec.ts`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #408
2026-05-30 18:09:16 +00:00

148 lines
5.0 KiB
Plaintext

---
import { getImage } from 'astro:assets';
import { OG, SEO, SITE } from '@data/constants';
import faviconSvgSrc from '@images/icon.svg';
import faviconSrc from '@images/icon.png';
import {
getLocaleFromPath,
isLocale,
localeOg,
localizedPath,
localizeRoutePath,
stripLocalePrefix,
type Locale,
} from '@/i18n';
// Default properties for the Meta component. These values are used if props are not provided.
// 'meta' sets a default description meta tag to describe the page content.
// 'structuredData' defines default structured data in JSON-LD format to enhance search engine understanding of the page (for SEO purposes).
const defaultProps = {
meta: SITE.description,
structuredData: SEO.structuredData,
customDescription: null,
customOgTitle: null,
};
// Extract props with default values assigned from defaultProps. Values can be overridden when the component is used.
// For example:
// <MainLayout title="Custom Title" meta="Custom description." />
const {
meta = defaultProps.meta,
structuredData = defaultProps.structuredData,
customDescription = defaultProps.customDescription,
customOgTitle = defaultProps.customOgTitle,
locale: rawLocale = getLocaleFromPath(Astro.url.pathname),
} = Astro.props;
const locale: Locale = isLocale(rawLocale) ? rawLocale : 'de';
// Use custom description if provided, otherwise use default meta
const description = customDescription || meta;
// Use custom OG title if provided, otherwise use default OG title
const ogTitle = customOgTitle || OG.title;
const ogDescription = customDescription || OG.description;
// Define the metadata for your website and individual pages
const siteURL = `${Astro.site}`; // Set the website URL in astro.config.mjs
const author = SITE.author;
const cleanPath = stripLocalePrefix(Astro.url.pathname);
const canonical = new URL(
localizedPath(cleanPath, locale),
Astro.site || Astro.url.origin
).href;
const socialImageRes = await getImage({
src: OG.image,
width: 1200,
height: 600,
format: 'png',
});
const socialImage = new URL(socialImageRes.src, Astro.site || Astro.url.origin)
.href;
const twitterDomain = new URL(siteURL).hostname;
const alternateLocales: Locale[] = ['de', 'en'];
// Generate and optimize the favicon images
const faviconSvg = await getImage({
src: faviconSvgSrc,
format: 'svg',
});
const appleTouchIcon = await getImage({
src: faviconSrc,
width: 180,
height: 180,
format: 'png',
});
---
{
/* Inject structured data into the page if provided. This data is formatted as JSON-LD, a method recommended by Google for structured data pass:
https://developers.google.com/search/docs/advanced/structured-data/intro-structured-data */
}{
structuredData && (
<script
type="application/ld+json"
set:html={JSON.stringify(structuredData)}
/>
)
}
{/* Define the character set, description, author, and viewport settings */}
<meta charset="utf-8" />
<meta content={description} name="description" />
<meta name="web_author" content={author} />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="canonical" href={canonical} />
{
alternateLocales.map(lang => {
const href = new URL(
localizeRoutePath(cleanPath, locale, lang),
Astro.site || Astro.url.origin
).href;
return <link rel="alternate" hreflang={lang} href={href} />;
})
}
<link
rel="alternate"
hreflang="x-default"
href={new URL(
localizeRoutePath(cleanPath, locale, 'de'),
Astro.site || Astro.url.origin
).href}
/>
{/* Facebook Meta Tags */}
<meta property="og:locale" content={localeOg[locale]} />
<meta property="og:url" content={canonical} />
<meta property="og:type" content="website" />
<meta property="og:title" content={ogTitle} />
<meta property="og:site_name" content={SITE.title} />
<meta property="og:description" content={ogDescription} />
<meta property="og:image" content={socialImage} />
<meta content="1200" property="og:image:width" />
<meta content="600" property="og:image:height" />
<meta content="image/png" property="og:image:type" />
{/* Twitter Meta Tags */}
<meta name="twitter:card" content="summary_large_image" />
<meta property="twitter:domain" content={twitterDomain} />
<meta property="twitter:url" content={canonical} />
<meta name="twitter:title" content={ogTitle} />
<meta name="twitter:description" content={ogDescription} />
<meta name="twitter:image" content={socialImage} />
{/* Links to the webmanifest and sitemap */}
<link rel="manifest" href="/manifest.json" />
{/* https://docs.astro.build/en/guides/integrations-guide/sitemap/ */}
<link rel="sitemap" href="/sitemap-index.xml" />
{/* Links for favicons */}
<link href="/favicon.ico" rel="icon" sizes="any" type="image/x-icon" />
<link href={faviconSvg.src} rel="icon" type="image/svg+xml" sizes="any" />
<meta name="mobile-web-app-capable" content="yes" />
<link href={appleTouchIcon.src} rel="apple-touch-icon" />
<link href={appleTouchIcon.src} rel="shortcut icon" />
{/* Set theme color */}
<meta name="theme-color" content="#facc15" />