mirror of
https://github.com/warmbly/warmbly.git
synced 2026-10-03 16:02:02 +00:00
feat: replace the marketing site's Open Graph and Twitter card with a top-left 1.91:1 crop of the new dashboard export, and derive og:image type, width and height from the real image so blog covers stop declaring 1280x640 jpeg
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 672 KiB After Width: | Height: | Size: 304 KiB |
@@ -9,8 +9,9 @@
|
||||
* web-app-manifest-192x192.png
|
||||
* web-app-manifest-512x512.png
|
||||
*
|
||||
* The 1200x600 OG / Twitter card (public/og-image.jpg) is exported from the
|
||||
* Figma Branding file (the "Social" frame), not generated here.
|
||||
* The 1920x1008 OG / Twitter card (public/og-image.jpg) is a top-left crop of
|
||||
* the 1920x1080 Figma "Social" frame export, not generated here. The crop is
|
||||
* to 1.91:1 (1200x630 x1.6), so the frame's top-left never gets cut.
|
||||
*
|
||||
* Run with: node scripts/gen-icons.mjs
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,8 @@ const canonical = new URL(Astro.url.pathname, Astro.site ?? 'https://warmbly.com
|
||||
// Per-post social/share image: use the post cover when set, else the site card.
|
||||
const shareImage = cover ?? '/og-image.jpg';
|
||||
const shareImageAbsolute = new URL(shareImage, Astro.site ?? 'https://warmbly.com').toString();
|
||||
// Covers in public/blog are all exported at 1200x600; the site card is 1920x1008.
|
||||
const shareImageSize = cover ? { w: 1200, h: 600 } : { w: 1920, h: 1008 };
|
||||
|
||||
const articleJsonLd = {
|
||||
'@context': 'https://schema.org',
|
||||
@@ -61,7 +63,7 @@ const neighbors = [
|
||||
next ? { label: 'Up next', post: next } : null,
|
||||
].filter(Boolean) as { label: string; post: BlogPost }[];
|
||||
---
|
||||
<Layout title={`${title} | Warmbly Blog`} description={description} ogImage={shareImage} ogType="article" jsonLd={[articleJsonLd, breadcrumbJsonLd]}>
|
||||
<Layout title={`${title} | Warmbly Blog`} description={description} ogImage={shareImage} ogImageWidth={shareImageSize.w} ogImageHeight={shareImageSize.h} {...(cover ? { ogImageAlt: title } : {})} ogType="article" jsonLd={[articleJsonLd, breadcrumbJsonLd]}>
|
||||
<!-- TOP BAR: sticky under the site header, carries the reading progress -->
|
||||
<div class="sticky top-14 z-30 bg-white/90 backdrop-blur-md border-b border-[color:var(--border)]">
|
||||
<div class="container-page py-3 flex items-center justify-between text-[11.5px] font-mono">
|
||||
|
||||
@@ -8,6 +8,10 @@ interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
ogImage?: string;
|
||||
/** Real pixel size of ogImage; scrapers render the card before fetching it. */
|
||||
ogImageWidth?: number;
|
||||
ogImageHeight?: number;
|
||||
ogImageAlt?: string;
|
||||
/** og:type — 'website' for most pages, 'article' for Learn essays */
|
||||
ogType?: string;
|
||||
/** Extra structured data injected per-page (e.g. BlogPosting, SoftwareApplication) */
|
||||
@@ -21,6 +25,9 @@ const {
|
||||
title,
|
||||
description = 'Warmbly is the deliverability platform for cold email. Warm your inboxes, send at scale, keep your reputation clean.',
|
||||
ogImage = '/og-image.jpg',
|
||||
ogImageWidth = 1920,
|
||||
ogImageHeight = 1008,
|
||||
ogImageAlt = 'The Warmbly dashboard, showing the unified inbox across connected mailboxes',
|
||||
ogType = 'website',
|
||||
jsonLd,
|
||||
noIndex = false,
|
||||
@@ -42,6 +49,12 @@ const posthogUiHost = import.meta.env.PUBLIC_POSTHOG_UI_HOST ?? 'https://us.post
|
||||
const siteOrigin = (Astro.site ?? new URL('https://warmbly.com')).toString().replace(/\/$/, '');
|
||||
const canonical = new URL(Astro.url.pathname, Astro.site ?? 'https://warmbly.com').toString();
|
||||
const ogImageAbsolute = new URL(ogImage, Astro.site ?? 'https://warmbly.com').toString();
|
||||
// Blog covers are .webp; declaring them as jpeg makes some scrapers skip the card.
|
||||
const ogImageType = ogImage.endsWith('.webp')
|
||||
? 'image/webp'
|
||||
: ogImage.endsWith('.png')
|
||||
? 'image/png'
|
||||
: 'image/jpeg';
|
||||
|
||||
// Schema.org Organization payload, sourced from the real company record.
|
||||
const organizationJsonLd = {
|
||||
@@ -125,10 +138,10 @@ const websiteJsonLd = {
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:image" content={ogImageAbsolute} />
|
||||
<meta property="og:image:secure_url" content={ogImageAbsolute} />
|
||||
<meta property="og:image:type" content="image/jpeg" />
|
||||
<meta property="og:image:width" content="1280" />
|
||||
<meta property="og:image:height" content="640" />
|
||||
<meta property="og:image:alt" content="Warmbly: the open-source cold email platform" />
|
||||
<meta property="og:image:type" content={ogImageType} />
|
||||
<meta property="og:image:width" content={String(ogImageWidth)} />
|
||||
<meta property="og:image:height" content={String(ogImageHeight)} />
|
||||
<meta property="og:image:alt" content={ogImageAlt} />
|
||||
|
||||
<!-- Twitter / X -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
@@ -137,7 +150,7 @@ const websiteJsonLd = {
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={ogImageAbsolute} />
|
||||
<meta name="twitter:image:alt" content="Warmbly: the open-source cold email platform" />
|
||||
<meta name="twitter:image:alt" content={ogImageAlt} />
|
||||
|
||||
<!-- Crawler hints -->
|
||||
<meta name="robots" content={noIndex ? 'noindex,nofollow' : 'index,follow,max-image-preview:large,max-snippet:-1'} />
|
||||
|
||||
Reference in New Issue
Block a user