"astro": "5.11.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
- "recharts": "^3.0.2",
+ "recharts": "^3.1.0",
},
"devDependencies": {
- "@types/bun": "^1.2.17",
+ "@types/bun": "^1.2.18",
},
},
},
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
- "recharts": ["recharts@3.0.2", "", { "dependencies": { "@reduxjs/toolkit": "1.x.x || 2.x.x", "clsx": "^2.1.1", "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", "immer": "^10.1.1", "react-redux": "8.x.x || 9.x.x", "reselect": "5.1.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-eDc3ile9qJU9Dp/EekSthQPhAVPG48/uM47jk+PF7VBQngxeW3cwQpPHb/GHC1uqwyCRWXcIrDzuHRVrnRryoQ=="],
+ "recharts": ["recharts@3.1.0", "", { "dependencies": { "@reduxjs/toolkit": "1.x.x || 2.x.x", "clsx": "^2.1.1", "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", "immer": "^10.1.1", "react-redux": "8.x.x || 9.x.x", "reselect": "5.1.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-NqAqQcGBmLrfDs2mHX/bz8jJCQtG2FeXfE0GqpZmIuXIjkpIwj8sd9ad0WyvKiBKPd8ZgNG0hL85c8sFDwascw=="],
"recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="],
<meta name="author" content={SiteMetadata.author.name} />
<meta name="generator" content={Astro.generator} />
<meta name="fediverse:creator" content={SiteMetadata.socials.activitypub.username} />
-<meta name="twitter:card" content="summary" />
+<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:creator" content={SiteMetadata.socials.x.username} />
<meta name="twitter:title" content={`${title} | ${SiteMetadata.title}`} />
<meta name="twitter:description" content={description} />
import { getCollection } from 'astro:content';
import { formatDate } from '@utils/format.ts';
import { ImageResponse } from '@vercel/og';
+import SiteMetadata from '@data/metadata.json';
export async function getStaticPaths() {
const articles = await getCollection('articles');
}));
};
-export const GET: APIRoute = ({ props }) => {
+async function loadFont() {
+ const url = `https://cdn.jsdelivr.net/fontsource/fonts/public-sans@latest/latin-400-normal.ttf`
+ const font = await fetch(url);
+ if (font) {
+ return await font.arrayBuffer()
+ }
+
+ throw new Error('failed to load font data')
+};
+
+export const GET: APIRoute = async ({ props }) => {
const element = {
type: 'div',
props: {
style: {
- fontSize: 40,
- color: 'black',
- background: 'white',
- width: '100%',
- height: '100%',
- padding: '50px 200px',
- textAlign: 'center',
+ display: 'flex',
+ flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
- display: 'flex'
+ backgroundColor: '#555555',
+ color: '#ffffff',
+ width: '100%',
+ height: '100%',
+ padding: 80,
+ fontFamily: 'Public Sans Variable',
},
children: [
{
- type: 'div',
+ type: 'h1',
+ props: {
+ style: {
+ fontSize: 64,
+ fontWeight: 600,
+ marginBottom: 20,
+ },
+ children: props.article.data.title,
+ },
+ },
+ {
+ type: 'p',
props: {
- children: props.article.data.title
- }
+ style: {
+ fontSize: 32,
+ marginBottom: 40,
+ },
+ children: props.article.data.description,
+ },
},
{
type: 'div',
props: {
- children: props.article.data.description
- }
- }
- ]
+ style: {
+ marginTop: 'auto',
+ textTransform: 'uppercase',
+ fontSize: 20,
+ fontWeight: 500,
+ letterSpacing: '0.1em',
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ children: [
+ {
+ type: 'div',
+ props: {
+ style: {
+ borderTop: '2px solid #ffffff',
+ width: 240,
+ margin: '0 auto 8px',
+ display: 'flex',
+ textAlign: 'center'
+ },
+ },
+ },
+ SiteMetadata.author.name,
+ ],
+ },
+ },
+ ],
+ },
+ }
+ return new ImageResponse(element, {
+ width: 1200,
+ height: 630,
+ fonts: [
+ {
+ name: 'Public Sans Variable',
+ data: await loadFont(),
+ style: 'normal'
}
- };
- return new ImageResponse(element, { width: 1200, height: 630 });
+ ]
+ });
};
\ No newline at end of file