From 40deb772b56fded74d56fce2f0a1e03a8d879640 Mon Sep 17 00:00:00 2001 From: Stefano Verna Date: Thu, 21 Nov 2024 11:22:34 +0100 Subject: [PATCH] SEO --- .../InterstitialTitle/style.module.css | 1 + src/layouts/docs/PageLayout/Component.astro | 6 +-- src/lib/datocms/seo.ts | 23 ++++++--- src/lib/ogCardUrl.ts | 6 +-- src/pages/og-card/index.png.ts | 51 +++++++------------ src/pages/partners/[partnerSlug]/index.astro | 16 +++++- src/pages/partners/index.astro | 6 ++- src/pages/tech-partners/[slug]/index.astro | 16 +++++- 8 files changed, 76 insertions(+), 49 deletions(-) diff --git a/src/components/InterstitialTitle/style.module.css b/src/components/InterstitialTitle/style.module.css index 91d690d3..a0fab852 100644 --- a/src/components/InterstitialTitle/style.module.css +++ b/src/components/InterstitialTitle/style.module.css @@ -88,6 +88,7 @@ .subtitle { margin-top: rfs(60px); + line-height: 1.1; } .bigSubtitle { diff --git a/src/layouts/docs/PageLayout/Component.astro b/src/layouts/docs/PageLayout/Component.astro index 54e577fc..e468317e 100644 --- a/src/layouts/docs/PageLayout/Component.astro +++ b/src/layouts/docs/PageLayout/Component.astro @@ -5,7 +5,7 @@ import { Image } from '~/components/blocks/Image'; import { InternalVideo } from '~/components/blocks/InternalVideo'; import { CloneButtonForm } from '~/components/docs/blocks/CloneButtonForm'; import { Demo } from '~/components/blocks/Demo'; -import { overrideSeo, changeOgCard } from '~/lib/datocms/seo'; +import { overrideSeo, generateCard, replacePageTitle } from '~/lib/datocms/seo'; import { DeployButtonForm } from '~/components/docs/blocks/DeployButtonForm'; import { DocCallout } from '~/components/docs/blocks/DocCallout'; import { MultipleDemosBlock } from '~/components/blocks/MultipleDemosBlock'; @@ -65,9 +65,9 @@ const tocGroups = [ group={maskedGroup} additionalSeo={overrideSeo( page._seoMetaTags, - changeOgCard({ + generateCard(Astro.url, { kicker: group ? `Documentation: ${group.name}` : 'DatoCMS Docs', - title: page.seo?.title || page.title, + title: page.title, pills: tocGroups.flatMap((group) => group.entries).map((entry) => entry.label), excerpt: page.seo?.description, }), diff --git a/src/lib/datocms/seo.ts b/src/lib/datocms/seo.ts index bbbe8979..8369ec92 100644 --- a/src/lib/datocms/seo.ts +++ b/src/lib/datocms/seo.ts @@ -28,24 +28,31 @@ function editMetaValue(propertyOrName: string, newValue: string) { }); } -export function changeTitle(newTitle: string) { +export function replacePageTitle(newTitle: string) { return editTagContent('title', newTitle); } -export function changeOgCard(data: OgCardData) { - const url = ogCardUrl(data); +export function replaceShareTitle(newTitle: string) { + return [editMetaValue('og:title', newTitle), editMetaValue('twitter:title', newTitle)]; +} + +export const ogCardWidth = 1200; +export const ogCardHeight = 700; + +export function generateCard(baseUrl: URL, data: OgCardData) { + const url = ogCardUrl(data, baseUrl); return [ editMetaValue('og:image', url), - editMetaValue('og:image:width', '1200'), - editMetaValue('og:image:height', '675'), + editMetaValue('og:image:width', ogCardWidth.toString()), + editMetaValue('og:image:height', ogCardHeight.toString()), editMetaValue('twitter:image', url), - editMetaValue('twitter:image:width', '1200'), - editMetaValue('twitter:image:height', '675'), + editMetaValue('twitter:image:width', ogCardWidth.toString()), + editMetaValue('twitter:image:height', ogCardHeight.toString()), ]; } -export function changeDescription(newDescription: string) { +export function replaceDescription(newDescription: string) { return [ editMetaValue('description', newDescription), editMetaValue('twitter:description', newDescription), diff --git a/src/lib/ogCardUrl.ts b/src/lib/ogCardUrl.ts index 1af2df0a..02da7b59 100644 --- a/src/lib/ogCardUrl.ts +++ b/src/lib/ogCardUrl.ts @@ -5,8 +5,8 @@ export type OgCardData = { excerpt?: string | null; }; -export function ogCardUrl(data: OgCardData): string { - const url = new URL('/og-card.png', 'http://bogus.com'); +export function ogCardUrl(data: OgCardData, baseUrl: URL): string { + const url = new URL('/og-card.png', baseUrl); url.searchParams.set('data', JSON.stringify(data)); - return url.pathname + url.search; + return url.toString(); } diff --git a/src/pages/og-card/index.png.ts b/src/pages/og-card/index.png.ts index 1517c971..1576fc96 100644 --- a/src/pages/og-card/index.png.ts +++ b/src/pages/og-card/index.png.ts @@ -3,25 +3,11 @@ import satori from 'satori'; import { html } from 'satori-html'; import sharp from 'sharp'; import css from 'style-object-to-css-string'; -import { graphql } from '~/lib/datocms/graphql'; +import { ogCardHeight, ogCardWidth } from '~/lib/datocms/seo'; import type { OgCardData } from '~/lib/ogCardUrl'; import { invalidRequestResponse } from '~/pages/api/_utils'; import FullLogo from './_resources/logo.svg?raw'; -const query = graphql(/* GraphQL */ ` - query OgImage($id: ItemId!) { - page: docPage(filter: { id: { eq: $id } }) { - title - parents: _allReferencingDocGroups { - name - } - content { - value - } - } - } -`); - function filterPills(pills: string[]): string[] { const result: string[] = []; let totalLength = 0; @@ -81,7 +67,6 @@ export const GET: APIRoute = async ({ url }) => { flexDirection: 'column', alignItems: 'center', justifyContent: 'center', - fontWeight: 'bold', gap: '20px', })}" > @@ -92,6 +77,7 @@ export const GET: APIRoute = async ({ url }) => { letterSpacing: '-0.04em', textTransform: 'uppercase', display: 'flex', + fontWeight: 'bold', })}" > ${kicker} @@ -100,26 +86,27 @@ export const GET: APIRoute = async ({ url }) => { style="${css({ fontSize: `${title.length < 40 ? 90 : 70}px`, letterSpacing: '-0.06em', - lineHeight: '1', + lineHeight: '0.9', display: 'flex', + fontWeight: 'bold', })}" > ${title} + ${excerpt + ? ` +
+ ${excerpt} +
+ ` + : ''} - ${excerpt - ? ` -
- ${excerpt} -
- ` - : ''} ${pills && pills.length > 1 ? `
{ `); const svg = await satori(markup as any, { - width: 1200, - height: 675, + width: ogCardWidth, + height: ogCardHeight, fonts: [ { name: 'colfax', diff --git a/src/pages/partners/[partnerSlug]/index.astro b/src/pages/partners/[partnerSlug]/index.astro index b4226207..53eef213 100644 --- a/src/pages/partners/[partnerSlug]/index.astro +++ b/src/pages/partners/[partnerSlug]/index.astro @@ -17,6 +17,13 @@ import { query, extraQuery } from './_graphql'; import { render as structuredTextToPlainText } from 'datocms-structured-text-to-plain-text'; import s from './_style.module.css'; import { PluginCard } from '~/pages/marketplace/_sub/PluginCard'; +import { + overrideSeo, + replaceDescription, + replacePageTitle, + replaceShareTitle, +} from '~/lib/datocms/seo'; +import { render as toPlainText } from 'datocms-structured-text-to-plain-text'; const { partnerSlug } = Astro.params; const variables = { partnerSlug: partnerSlug! }; @@ -32,7 +39,14 @@ const { plugins } = await executeQuery(Astro, extraQuery, { }); --- - + DatoCMS Agency Partner diff --git a/src/pages/partners/index.astro b/src/pages/partners/index.astro index 215f46e0..de1f44b1 100644 --- a/src/pages/partners/index.astro +++ b/src/pages/partners/index.astro @@ -147,7 +147,11 @@ const getLabel = (count: number) => { const bkgColors = ['azure', 'pink', 'blue', 'green', 'yellow'] as const; --- - + + + DatoCMS Solution Partners + + Solution Partners diff --git a/src/pages/tech-partners/[slug]/index.astro b/src/pages/tech-partners/[slug]/index.astro index 9ea7d9d6..0b4bf543 100644 --- a/src/pages/tech-partners/[slug]/index.astro +++ b/src/pages/tech-partners/[slug]/index.astro @@ -10,6 +10,13 @@ import { avoidAstroTypeCheckBug, notFoundResponse } from '~/lib/notFoundResponse import { executeQuery } from '~/lib/datocms/executeQuery'; import { query } from './_graphql'; import s from './_style.module.css'; +import { + overrideSeo, + replaceDescription, + replacePageTitle, + replaceShareTitle, +} from '~/lib/datocms/seo'; +import { render as toPlainText } from 'datocms-structured-text-to-plain-text'; const { slug } = Astro.params; const variables = { slug: slug! }; @@ -21,7 +28,14 @@ if (!page) { } --- - + DatoCMS Technology Partner