Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions kubernetes/loculus/templates/_common-metadata.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ welcomeMessageHTML: {{ quote $.Values.welcomeMessageHTML }}
{{ if $.Values.additionalHeadHTML }}
additionalHeadHTML: {{ quote $.Values.additionalHeadHTML }}
{{end}}
{{ if $.Values.openGraph }}
openGraph: {{ $.Values.openGraph | toYaml | nindent 6 }}
{{ end }}

enableLoginNavigationItem: {{ $.Values.website.websiteConfig.enableLoginNavigationItem }}
enableSubmissionNavigationItem: {{ $.Values.website.websiteConfig.enableSubmissionNavigationItem }}
Expand Down
21 changes: 21 additions & 0 deletions kubernetes/loculus/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,27 @@
"type": "string",
"description": "Additional HTML to inject into the <head> of pages"
},
"openGraph": {
"groups": ["general"],
"type": "object",
"additionalProperties": false,
"description": "Default Open Graph / social card metadata. Used when no per-organism image is configured (organism-specific images are taken from each organism's `schema.image`).",
"properties": {
"image": {
"type": "string",
"description": "Default Open Graph image. Relative paths are resolved against the page URL."
},
"description": {
"type": "string",
"description": "Default Open Graph / meta description for pages."
},
"twitterCard": {
"type": "string",
"enum": ["summary", "summary_large_image", "player", "app"],
"description": "Value for `<meta name=\"twitter:card\">`. When unset, defaults to `summary_large_image` if a card image is configured (per-organism or site-wide), otherwise `summary`."
}
}
},
"createTestAccounts": {
"groups": ["general"],
"type": "boolean",
Expand Down
16 changes: 15 additions & 1 deletion website/src/layouts/BaseLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const {
additionalHeadHTML,
gitHubMainUrl,
readOnlyMode,
openGraph,
} = websiteConfig;
const remoteBannerMessage = await getRemoteBannerMessage();
const readOnlyBannerMessage = readOnlyMode
Expand All @@ -29,19 +30,25 @@ const bannerMessage = remoteBannerMessage ?? configBannerMessage ?? readOnlyBann

interface Props {
title: string;
description?: string;
implicitOrganism?: string;
fullWidth?: boolean;
withoutMargin?: boolean;
activeTopNavigationItem?: string;
}

const { title, implicitOrganism, fullWidth, withoutMargin = false, activeTopNavigationItem } = Astro.props;
const { title, description, implicitOrganism, fullWidth, withoutMargin = false, activeTopNavigationItem } = Astro.props;

const { organism, knownOrganisms } = cleanOrganism(Astro.params.organism);
const implicitOrganismObject = implicitOrganism ? knownOrganisms.find((o) => o.key === implicitOrganism) : undefined;
const currentOrganismObject = implicitOrganismObject || organism;
const currentOrganism = currentOrganismObject?.key;

const rawSocialCardImage = currentOrganismObject?.image ?? openGraph?.image;
const socialCardImage = rawSocialCardImage ? new URL(rawSocialCardImage, Astro.url).toString() : undefined;
const socialCardDescription = description ?? openGraph?.description;
const twitterCard = openGraph?.twitterCard ?? (socialCardImage ? 'summary_large_image' : 'summary');

const currentPath = Astro.url.pathname;

const backendIsInDebugMode = await createBackendClient().isInDebugMode();
Expand All @@ -56,10 +63,17 @@ const lastTimeBannerWasClosed = Astro.cookies.get('lastTimeBannerWasClosed')?.va
<link rel='preload' as='image' href='/favicon.svg' />
<meta name='viewport' content='width=device-width' />
<meta name='generator' content={Astro.generator} />
<meta property='og:type' content='website' />
<meta property='og:url' content={Astro.url} />
<meta property='og:title' content={websiteName + ' | ' + title} />
{socialCardDescription && <meta property='og:description' content={socialCardDescription} />}
{socialCardImage && <meta property='og:image' content={socialCardImage} />}
<meta name='twitter:card' content={twitterCard} />
<meta property='twitter:url' content={Astro.url} />
<meta property='twitter:title' content={websiteName + ' | ' + title} />
{socialCardDescription && <meta property='twitter:description' content={socialCardDescription} />}
{socialCardImage && <meta property='twitter:image' content={socialCardImage} />}
{socialCardDescription && <meta name='description' content={socialCardDescription} />}
<title>{title} | {websiteName}</title>
<Fragment set:html={additionalHeadHTML} />
</head>
Expand Down
8 changes: 8 additions & 0 deletions website/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,13 @@ const fieldToDisplay = z.object({
displayName: z.string(),
});

const openGraphConfig = z.object({
image: z.string().optional(),
description: z.string().optional(),
twitterCard: z.enum(['summary', 'summary_large_image', 'player', 'app']).optional(),
});
export type OpenGraphConfig = z.infer<typeof openGraphConfig>;

const seqSetGraphTypes = z.enum(['date', 'category']);
export const seqSetGraph = z.object({
name: z.string(),
Expand All @@ -258,6 +265,7 @@ export const websiteConfig = z.object({
submissionBannerMessageURL: z.string().optional(),
welcomeMessageHTML: z.string().optional().nullable(),
additionalHeadHTML: z.string().optional(),
openGraph: openGraphConfig.optional(),
gitHubEditLink: z.string().optional(),
gitHubMainUrl: z.string().optional(),
gitHubIssuesUrl: z.string().optional(),
Expand Down
Loading