From 5a0079a8a0b36cdffbf056b7815f4775894ff938 Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Wed, 23 Sep 2026 13:20:23 -0700 Subject: [PATCH 1/2] About page: add company facts section and AboutPage JSON-LD Adds a plain-text "Shorebird at a glance"
to /about and emits AboutPage + Organization JSON-LD there. The Organization node moves to src/lib/structured-data.ts so the home and About pages share one copy, and gains the founder's LinkedIn and Accel as funder. --- .cspell.yaml | 1 + src/lib/structured-data.ts | 73 +++++++++++++++++++++++++++++++ src/pages/about.astro | 88 ++++++++++++++++++++++++++++++++++++++ src/pages/index.astro | 59 +------------------------ 4 files changed, 164 insertions(+), 57 deletions(-) create mode 100644 src/lib/structured-data.ts diff --git a/.cspell.yaml b/.cspell.yaml index cce379e5..52f29aa7 100644 --- a/.cspell.yaml +++ b/.cspell.yaml @@ -78,6 +78,7 @@ words: - fouc - frontends - frontmatter + - funder - futureproof - gallego - ghisi diff --git a/src/lib/structured-data.ts b/src/lib/structured-data.ts new file mode 100644 index 00000000..41510045 --- /dev/null +++ b/src/lib/structured-data.ts @@ -0,0 +1,73 @@ +/** + * schema.org nodes shared by the pages that emit JSON-LD. Keep these in sync + * with the visible "Shorebird at a glance" facts on the About page so search + * engines and AI answers see one consistent set of company facts. + */ + +const siteUrl = 'https://shorebird.dev/'; + +export const founder = { + '@type': 'Person', + '@id': `${siteUrl}#eric-seidel`, + name: 'Eric Seidel', + jobTitle: 'CEO and Founder', + description: 'Creator of Flutter.', + sameAs: ['https://www.linkedin.com/in/ericseidel/'], +}; + +export const organization = { + '@type': 'Organization', + '@id': `${siteUrl}#organization`, + name: 'Shorebird', + url: siteUrl, + logo: { + '@type': 'ImageObject', + url: `${siteUrl}shorebird-logo-wordmark.png`, + width: 2568, + height: 560, + }, + description: + 'Shorebird builds developer tools for Flutter teams. Its flagship service, Code Push, delivers over-the-air Dart updates to released Flutter apps without waiting for app store review.', + foundingDate: '2023', + founder, + funder: { + '@type': 'Organization', + name: 'Accel', + url: 'https://www.accel.com/', + }, + sameAs: [ + 'https://github.com/shorebirdtech', + 'https://www.linkedin.com/company/shorebirddev/', + 'https://discord.gg/shorebird', + ], + contactPoint: [ + { + '@type': 'ContactPoint', + contactType: 'sales', + url: `${siteUrl}pricing`, + }, + { + '@type': 'ContactPoint', + contactType: 'technical support', + url: 'https://discord.gg/shorebird', + }, + ], + legalName: 'Code Town Inc', + address: { + '@type': 'PostalAddress', + streetAddress: '2261 Market Street #5112', + addressLocality: 'San Francisco', + addressRegion: 'CA', + postalCode: '94114-1612', + addressCountry: 'US', + }, +}; + +export const website = { + '@type': 'WebSite', + '@id': `${siteUrl}#website`, + url: siteUrl, + name: 'Shorebird', + publisher: { '@id': `${siteUrl}#organization` }, + inLanguage: 'en-US', +}; diff --git a/src/pages/about.astro b/src/pages/about.astro index 6ed71c3f..7d02235b 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -8,7 +8,9 @@ import Resources from '@/components/home/resources.astro'; import Section from '@/components/ui/section.astro'; import accelLogo from '@/assets/about/accel.webp'; import heroLogos from '@/assets/about/hero-logos.svg'; +import config from '@/config'; import teamData from '@/data/team.json'; +import { organization, website } from '@/lib/structured-data'; /** * Team grid (Webflow `.c_team--cms_list`): `src/data/team.json` is the @@ -26,6 +28,55 @@ const team = teamData return { ...member, image: image.default }; }); /** Webflow `.social_icn` LinkedIn glyph (14x14). */ +const structuredData = { + '@context': 'https://schema.org', + '@graph': [ + { + '@type': 'AboutPage', + '@id': 'https://shorebird.dev/about#webpage', + url: 'https://shorebird.dev/about', + name: 'About Shorebird', + isPartOf: { '@id': website['@id'] }, + about: { '@id': organization['@id'] }, + }, + organization, + website, + ], +}; + +/** + * "Shorebird at a glance": plain-text company facts for readers, search + * engines and AI answers. Mirrors `organization` in `@/lib/structured-data`. + */ +const facts: { term: string; detail: string; href?: string }[] = [ + { + term: 'What it is', + detail: + 'Developer tools for Flutter teams: over-the-air updates and CI for Flutter and Dart apps.', + }, + { + term: 'Products', + detail: + 'Code Push (over-the-air updates to released apps without app store review) and Shorebird CI (zero-config CI for Flutter and Dart).', + }, + { term: 'Founded', detail: '2023' }, + { term: 'Founder', detail: 'Eric Seidel, creator of Flutter' }, + { term: 'Headquarters', detail: 'San Francisco, California' }, + { term: 'Backed by', detail: 'Accel' }, + { + term: 'Pricing', + detail: 'Free plan, plus paid Pro, Business and Enterprise plans', + href: '/pricing', + }, + { + term: 'Open source', + detail: 'github.com/shorebirdtech', + href: 'https://github.com/shorebirdtech', + }, + { term: 'Docs', detail: 'docs.shorebird.dev', href: config.docsUrl }, + { term: 'Community', detail: 'Discord', href: config.discordUrl }, +]; + const linkedinIcon = ``; --- @@ -33,6 +84,13 @@ const linkedinIcon = ` + + + {/* Hero (Webflow `header.g_page--section` + `.c_hero--about--logos`). */} @@ -75,6 +133,36 @@ const linkedinIcon = ` + {/* Company facts as a
so they read as plain text to crawlers. */} +
+
+
+
+

Shorebird at a glance

+
+ +
+ { + facts.map(({ term, detail, href }) => ( +
+
{term}
+
+ {href ? ( + + {detail} + + ) : ( + detail + )} +
+
+ )) + } +
+
+
+
+ {/* Mission card (Webflow `.c_mission_card`: dark card on the light band). */}
Date: Wed, 23 Sep 2026 13:28:05 -0700 Subject: [PATCH 2/2] Drop the visible facts table; keep facts in JSON-LD and copy The table read as a spec sheet in the middle of the About page's story and gave crawlers little the JSON-LD doesn't. Mention Shorebird CI in the founding blurb instead. --- src/lib/structured-data.ts | 5 ++- src/pages/about.astro | 70 +++----------------------------------- 2 files changed, 6 insertions(+), 69 deletions(-) diff --git a/src/lib/structured-data.ts b/src/lib/structured-data.ts index 41510045..5d748e44 100644 --- a/src/lib/structured-data.ts +++ b/src/lib/structured-data.ts @@ -1,7 +1,6 @@ /** - * schema.org nodes shared by the pages that emit JSON-LD. Keep these in sync - * with the visible "Shorebird at a glance" facts on the About page so search - * engines and AI answers see one consistent set of company facts. + * schema.org nodes shared by the pages that emit JSON-LD, so the home and + * About pages describe the company identically. */ const siteUrl = 'https://shorebird.dev/'; diff --git a/src/pages/about.astro b/src/pages/about.astro index 7d02235b..2c403055 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -8,7 +8,6 @@ import Resources from '@/components/home/resources.astro'; import Section from '@/components/ui/section.astro'; import accelLogo from '@/assets/about/accel.webp'; import heroLogos from '@/assets/about/hero-logos.svg'; -import config from '@/config'; import teamData from '@/data/team.json'; import { organization, website } from '@/lib/structured-data'; @@ -27,7 +26,7 @@ const team = teamData if (!image) throw new Error(`Headshot ${member.headshot} not found`); return { ...member, image: image.default }; }); -/** Webflow `.social_icn` LinkedIn glyph (14x14). */ + const structuredData = { '@context': 'https://schema.org', '@graph': [ @@ -44,39 +43,7 @@ const structuredData = { ], }; -/** - * "Shorebird at a glance": plain-text company facts for readers, search - * engines and AI answers. Mirrors `organization` in `@/lib/structured-data`. - */ -const facts: { term: string; detail: string; href?: string }[] = [ - { - term: 'What it is', - detail: - 'Developer tools for Flutter teams: over-the-air updates and CI for Flutter and Dart apps.', - }, - { - term: 'Products', - detail: - 'Code Push (over-the-air updates to released apps without app store review) and Shorebird CI (zero-config CI for Flutter and Dart).', - }, - { term: 'Founded', detail: '2023' }, - { term: 'Founder', detail: 'Eric Seidel, creator of Flutter' }, - { term: 'Headquarters', detail: 'San Francisco, California' }, - { term: 'Backed by', detail: 'Accel' }, - { - term: 'Pricing', - detail: 'Free plan, plus paid Pro, Business and Enterprise plans', - href: '/pricing', - }, - { - term: 'Open source', - detail: 'github.com/shorebirdtech', - href: 'https://github.com/shorebirdtech', - }, - { term: 'Docs', detail: 'docs.shorebird.dev', href: config.docsUrl }, - { term: 'Community', detail: 'Discord', href: config.discordUrl }, -]; - +/** Webflow `.social_icn` LinkedIn glyph (14x14). */ const linkedinIcon = ``; --- @@ -127,42 +94,13 @@ const linkedinIcon = ` We care about making portable development the default and creating a rich and robust Flutter ecosystem. Our flagship service, Code Push, - enables instant app updates without app store delays. + enables instant app updates without app store delays, and Shorebird CI + brings zero-config continuous integration to Flutter and Dart.

- {/* Company facts as a
so they read as plain text to crawlers. */} -
-
-
-
-

Shorebird at a glance

-
- -
- { - facts.map(({ term, detail, href }) => ( -
-
{term}
-
- {href ? ( - - {detail} - - ) : ( - detail - )} -
-
- )) - } -
-
-
-
- {/* Mission card (Webflow `.c_mission_card`: dark card on the light band). */}