-
Notifications
You must be signed in to change notification settings - Fork 684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Dynamic og image #1344 #1616
Open
vasfvitor
wants to merge
100
commits into
tauri-apps:v2
Choose a base branch
from
vasfvitor:dynamic-og-images
base: v2
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+299
−27
Open
Changes from all commits
Commits
Show all changes
100 commits
Select commit
Hold shift + click to select a range
c044e22
kickstart dynamic og
vasfvitor 93dc3a3
Update [...path].png.ts
vasfvitor 9d3bef0
abstract breakText()
vasfvitor 2c4b469
og templates (short, long, blog)
vasfvitor 2bc0766
add TODO
vasfvitor 2cc6d5c
set /blog og image png
vasfvitor 4c0cfd2
move ts files to /assets
vasfvitor e18fe47
Update templates.ts
vasfvitor 7935d48
refactor - remove long/short templates
vasfvitor 5a018ed
feat: blog excerpt optional param
vasfvitor 34e68dc
set font (SF PRO 500)
vasfvitor 6c17be9
kickstart dynamic og
vasfvitor 4022623
Update [...path].png.ts
vasfvitor fccf10e
abstract breakText()
vasfvitor 60e923d
og templates (short, long, blog)
vasfvitor 8b14324
add TODO
vasfvitor 73f4ee7
set /blog og image png
vasfvitor 833d5a1
move ts files to /assets
vasfvitor c372881
Update templates.ts
vasfvitor dc769c3
refactor - remove long/short templates
vasfvitor a756f1d
feat: blog excerpt optional param
vasfvitor 8832790
set font (SF PRO 500)
vasfvitor df5e31e
Merge branch 'dynamic-og-images' of https://github.com/vasfvitor/taur…
vasfvitor 1210ddb
sanitize frontmatter
vasfvitor 05af38e
override head
vasfvitor 53fca0f
remove comment (fixed issue)
vasfvitor 204d853
fix: png output size to match svg's
vasfvitor a45dd74
font config
vasfvitor f8c9e93
fix: font config path
vasfvitor a4dc0ff
add reference
vasfvitor f5f60e3
add todo
vasfvitor 569ee21
refactor: OG head logic
vasfvitor f65de16
fix: trailing slash :+1: and edge cases
vasfvitor edffcbe
move const to utils
vasfvitor a153089
revert: move const to utils
vasfvitor b993510
basic setup astro-og-canvas
vasfvitor ec974ed
temp
vasfvitor 95b4894
Update [...docs].ts
vasfvitor afd3d05
Update Head.astro
vasfvitor 2f0dcc5
move files around
vasfvitor 068d977
00 hack
vasfvitor 7285217
Merge branch 'next' into dynamic-og-images
vasfvitor e57a436
Merge branch 'og-canvas-modified' into dynamic-og-images
vasfvitor 7d671ac
undo first draft changes
vasfvitor f7fbecf
resolve conflicts
vasfvitor 3f0d50b
done background
vasfvitor d03c769
patch extra field (for blog post date)
vasfvitor f574e70
patch force logo to bottom right on ltr
vasfvitor 1066e6d
removed head prop on config
vasfvitor 32c6b33
Update pnpm-lock.yaml
vasfvitor e57b2a6
bit cleanup
vasfvitor 247986d
add comments on 00 hack
vasfvitor a2a2ad8
change to use unchached image
vasfvitor 01d1009
Revert "change to use unchached image"
vasfvitor f18295c
add fonts and change sizes
vasfvitor 3e1bbf2
add preview page at `/preview`
vasfvitor ebfd535
Delete NotoSans_Condensed-Bold.ttf
vasfvitor 5f518df
improve font size strategy and add comments
vasfvitor 13ac3aa
use env var
vasfvitor 2d3dfb4
Update [...docs].ts
vasfvitor d9f14a6
undo patch-1
vasfvitor 2c623fa
undo patch-2
vasfvitor ee3fe94
update config without patch
vasfvitor e4f9df7
Update [...docs].ts
vasfvitor 8786bf8
logo size
vasfvitor cd7fbf0
font Inter, 2 lines, trim
vasfvitor ffa021b
remove unused date function
vasfvitor 8f205fc
update comments
vasfvitor 72b37d4
Merge branch 'next' into dynamic-og-images
vasfvitor 747f882
Noto Sans SC
vasfvitor de25f46
use Noto Sans non variable
vasfvitor e478bda
remove font files
vasfvitor 210c8c4
Create _open-graph-files.md
vasfvitor 49d3d73
reduce length to fix one image
vasfvitor a48dc91
format
vasfvitor b25db9b
remove preview page
vasfvitor 24830b4
skip og on non production builds
vasfvitor bed1eae
Merge branch 'next' into dynamic-og-images
vasfvitor bebeb96
build og on local dev
vasfvitor d6a787d
Merge branch 'dynamic-og-images' of https://github.com/vasfvitor/taur…
vasfvitor 60c97dd
Merge branch 'next' into dynamic-og-images
vasfvitor a1a614f
Update pnpm-lock.yaml
vasfvitor 684abe1
Merge branch 'next' into dynamic-og-images
vasfvitor 239495b
Update pnpm-lock.yaml
vasfvitor bacb77e
Update astro.config.mjs
vasfvitor 3edc067
Update package.json
vasfvitor c0419a7
Update pnpm-lock.yaml
vasfvitor 5f2f8dc
Update astro.config.mjs
vasfvitor c595656
Merge branch 'dynamic-og-images' of https://github.com/vasfvitor/taur…
vasfvitor 4f05919
Revert "Update astro.config.mjs"
vasfvitor 3b5e846
Revert "Update package.json"
vasfvitor 051b5a3
Revert "Update pnpm-lock.yaml"
vasfvitor ca398cd
Merge branch 'v2' into dynamic-og-images
vasfvitor 404908a
Update pnpm-lock.yaml
vasfvitor 41a2151
format
vasfvitor 3954ad7
Update astro.config.mjs
vasfvitor 1b2b8e0
better text fitting and ...
vasfvitor 452d553
override head
vasfvitor 49669c1
Create preview.astro
vasfvitor 050fa32
add is:inline
vasfvitor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
--- | ||
/** TODO: Check how to override the current metatag 'content' instead | ||
* so that the settings on @file astro.config can be utilized along | ||
* without conflicts. | ||
* | ||
* Tested with these (from Starlight source @file head.astro) but couldn't get around getting the | ||
* default head into a format to pass into the @function createHead | ||
* (virtual needs /// <reference path="../node_modules/@astrojs/starlight/virtual.d.ts"/> on @file env.ts) | ||
* | ||
* --- | ||
* import { createHead } from 'node_modules/@astrojs/starlight/utils/head'; | ||
* import config from 'virtual:starlight/user-config'; | ||
* const head = createHead(headDefaults, config.head, data.head); | ||
* --- | ||
* {head.map(({ tag: Tag, attrs, content }) => <Tag {...attrs} set:html={content} />)} | ||
* | ||
*/ | ||
|
||
import type { Props } from '@astrojs/starlight/props'; | ||
import Default from '@astrojs/starlight/components/Head.astro'; | ||
|
||
import { getOgImageUrl } from 'src/utils/getOgImageUrl'; | ||
|
||
const { isFallback } = Astro.props; | ||
const ogImageUrl = getOgImageUrl(Astro.url.pathname, !!isFallback); | ||
const imageSrc = ogImageUrl ?? 'og.png'; | ||
|
||
let canonicalImageSrc = new URL(imageSrc, Astro.site); | ||
|
||
// Override URL for development environment | ||
const isDev = import.meta.env.DEV; | ||
if (isDev) { | ||
canonicalImageSrc = new URL(imageSrc, Astro.url); | ||
} | ||
--- | ||
|
||
<Default {...Astro.props}><slot /></Default> | ||
|
||
<!-- og-images --> | ||
<meta property="og:image" content={canonicalImageSrc} /> | ||
<meta name="twitter:image" content={canonicalImageSrc} /> | ||
|
||
<!-- other --> | ||
<script is:inline src="/navigate.js"></script> | ||
<link rel="manifest" href="/manifest.json" /> | ||
<meta name="theme-color" content="#181818" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { allPages } from '../../utils/content'; | ||
|
||
// https://github.com/withastro/docs/blob/main/src/pages/0/0.ts | ||
// https://www.github.com/withastro/docs/pull/4266/commits/030073f32d6dfe586c6e1da8d48d6b5485541ba2 | ||
|
||
export function GET() { | ||
allPages[0]; | ||
return new Response(''); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import type { CollectionEntry } from 'astro:content'; | ||
import { OGImageRoute } from 'astro-og-canvas'; | ||
import { allPages } from 'src/utils/content'; | ||
|
||
// setup rtlLanguages here | ||
const rtlLanguages = new Set(['']); | ||
const getLangFromSlug = (slug: CollectionEntry<'docs'>['slug']) => slug.split('/')[0]; | ||
|
||
/** Paths for all of our Markdown content we want to generate OG images for. */ | ||
const paths = process.env.CONTEXT == 'production' || import.meta.env.DEV ? allPages : []; | ||
// const paths = allPages // use this to build locally | ||
|
||
/** An object mapping file paths to file metadata. */ | ||
const pages = Object.fromEntries(paths.map(({ id, slug, data }) => [id, { data, slug }])); | ||
|
||
/** | ||
* TODO: This can be improved | ||
* Helper function to clamp a string | ||
* @returns A string that fits in two lines with "..." at the end if text is longer than MAX_LEN | ||
*/ | ||
function clampTwoLines(txt: string, fontSize: number): string { | ||
// those numbers are what more or less fit to description and title size, not precisely | ||
// it can vary based on font, as of now it matches Inter. | ||
// Maybe this can help? https://github.com/adambisek/string-pixel-width/blob/master/src/pixelWidthCalculator.html | ||
// or this https://github.com/Evgenus/js-server-text-width | ||
let MAX_LEN = 73; | ||
// title: | ||
if (fontSize > 60) { | ||
MAX_LEN = 48; | ||
} | ||
if (txt.length > MAX_LEN) { | ||
txt = txt.trim().substring(0, MAX_LEN).trim(); | ||
txt[txt.length - 1] === '.' ? (txt += '..') : (txt += '...'); | ||
} | ||
const arTxt = breakText(txt, 2, 80 / 2); | ||
return arTxt.join(''); | ||
} | ||
|
||
function breakText(str: string, maxLines: number, maxLineLen: number) { | ||
const segmenterTitle = new Intl.Segmenter('en-US', { granularity: 'word' }); | ||
const segments = segmenterTitle.segment(str); | ||
|
||
let linesOut = ['']; | ||
let lineNo = 0; | ||
let offsetInLine = 0; | ||
for (const word of Array.from(segments)) { | ||
if (offsetInLine + word.segment.length >= maxLineLen) { | ||
lineNo++; | ||
offsetInLine = 0; | ||
linesOut.push(''); | ||
} | ||
|
||
if (lineNo >= maxLines) { | ||
return linesOut.slice(0, maxLines); | ||
} | ||
|
||
linesOut[lineNo] += word.segment; | ||
offsetInLine += word.segment.length; | ||
} | ||
|
||
return linesOut; | ||
} | ||
|
||
// REFERENCE: | ||
// https://github.com/delucis/astro-og-canvas/tree/latest/packages/astro-og-canvas | ||
export const { getStaticPaths, GET } = OGImageRoute({ | ||
param: 'docs', | ||
pages, | ||
getImageOptions: async (_, { data, slug }: (typeof pages)[string]) => { | ||
/** titleSize and descSize are coupled with @function clampTwoLines() */ | ||
let [titleSize, descSize] = [72, 48]; | ||
let description = ''; | ||
let title = clampTwoLines(data.title, titleSize); | ||
if (data.description) { | ||
description = clampTwoLines(data.description, descSize); | ||
} | ||
if (slug.startsWith('blog/') && data.date && data.excerpt) { | ||
description = clampTwoLines(data.excerpt, descSize); | ||
} | ||
return { | ||
title, | ||
description, | ||
dir: rtlLanguages.has(getLangFromSlug(slug)) ? 'rtl' : 'ltr', | ||
padding: 66, | ||
bgImage: { path: './src/assets/og-bg.png' }, | ||
logo: { path: './src/assets/og-logo.png' }, | ||
font: { | ||
title: { | ||
/** Size is coupled with @function clampTwoLines() */ | ||
size: titleSize, | ||
lineHeight: 1.25, | ||
weight: 'Normal', | ||
families: ['Inter', 'Noto Sans SC Thin'], | ||
}, | ||
description: { | ||
/** Size is coupled with @function clampTwoLines() */ | ||
size: descSize, | ||
lineHeight: 1.25, | ||
weight: 'Normal', | ||
families: ['Inter', 'Noto Sans SC Thin'], | ||
}, | ||
}, | ||
fonts: [ | ||
'./node_modules/@fontsource-variable/inter/files/inter-latin-standard-normal.woff2', | ||
// simplified chinese | ||
'./node_modules/@fontsource/noto-sans-sc/files/noto-sans-sc-chinese-simplified-400-normal.woff2', | ||
], | ||
}; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Open Graph files: | ||
|
||
```sh | ||
src/assets/og-bg.png - Background image | ||
src/assets/og-logo.png - Logo image | ||
src/components/overrides/Head.astro - Head override to inject social metatags | ||
src/pages/0/0.ts - Chris\'s "00 hack" to make it work in Starlight in this specific setup | ||
src/utils/content.ts - Export docs collection | ||
src/utils/getOgImageUrl.ts - Used in the head override to get the url for current page | ||
src/pages/open-graph/[...docs].ts - Customize and generate each image and rtlLanguages | ||
``` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can't find an issue, can we open one to point to so we know when this hack may be replaced by an improved implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://www.github.com/withastro/astro/issues/8972