1---
2/**
3 * Schema.org JSON-LD for the site: an `Organization` (with `sameAs` pointing
4 * at our social profiles so search engines link them to the brand) and the
5 * `WebSite` it publishes. Emitted on every page — marketing and docs — so the
6 * knowledge-panel signals don't depend on which URL gets crawled first.
7 *
8 * URLs are always built against `Astro.site` (the canonical origin), never
9 * the request host, so mirrors and previews describe production.
10 */
11const site = Astro.site ?? new URL("https://alchemy.run");
12const organizationId = new URL("/#organization", site).href;
13
14const SOCIAL_PROFILES = {
15 github: "https://github.com/alchemy-run/alchemy",
16 x: new URL("/twitter", site).href,
17 discord: new URL("/discord", site).href,
18 npm: "https://www.npmjs.com/package/alchemy",
19} as const;
20
21const organization = {
22 "@context": "https://schema.org",
23 "@type": "Organization",
24 "@id": organizationId,
25 name: "Alchemy",
26 url: site.href,
27 logo: new URL("/alchemy-logo-512-white-bg.png", site).href,
28 sameAs: Object.values(SOCIAL_PROFILES),
29};
30
31const website = {
32 "@context": "https://schema.org",
33 "@type": "WebSite",
34 "@id": new URL("/#website", site).href,
35 name: "Alchemy",
36 url: site.href,
37 publisher: { "@id": organizationId },
38};
39
40// `</script` inside a JSON string would end the block early; escape `<`.
41const json = (value: unknown) =>
42 JSON.stringify(value).replaceAll("<", "\\u003c");
43---
44
45<script is:inline type="application/ld+json" set:html={json(organization)} />
46<script is:inline type="application/ld+json" set:html={json(website)} />