mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 03:32:51 +02:00
test: og url end with slash
This commit is contained in:
parent
79f9765688
commit
c97e3d5882
9 changed files with 82 additions and 15 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -67,6 +67,7 @@
|
||||||
"Beze",
|
"Beze",
|
||||||
"blurhash",
|
"blurhash",
|
||||||
"bmoji",
|
"bmoji",
|
||||||
|
"canvaskit",
|
||||||
"Disqus",
|
"Disqus",
|
||||||
"Etiquetas",
|
"Etiquetas",
|
||||||
"Frontmatter",
|
"Frontmatter",
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
"@rehype-pretty/transformers": "^0.13.2",
|
"@rehype-pretty/transformers": "^0.13.2",
|
||||||
"astro": "^5.4.3",
|
"astro": "^5.4.3",
|
||||||
"astro-compress": "^2.3.6",
|
"astro-compress": "^2.3.6",
|
||||||
|
"astro-og-canvas": "^0.7.0",
|
||||||
"astro-robots-txt": "^1.0.0",
|
"astro-robots-txt": "^1.0.0",
|
||||||
|
"canvaskit-wasm": "^0.39.1",
|
||||||
"hastscript": "^9.0.1",
|
"hastscript": "^9.0.1",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"overlayscrollbars": "^2.11.1",
|
"overlayscrollbars": "^2.11.1",
|
||||||
|
|
31
pnpm-lock.yaml
generated
31
pnpm-lock.yaml
generated
|
@ -32,9 +32,15 @@ importers:
|
||||||
astro-compress:
|
astro-compress:
|
||||||
specifier: ^2.3.6
|
specifier: ^2.3.6
|
||||||
version: 2.3.6(@types/node@22.13.10)(jiti@2.4.2)(rollup@4.35.0)(typescript@5.8.2)(yaml@2.7.0)
|
version: 2.3.6(@types/node@22.13.10)(jiti@2.4.2)(rollup@4.35.0)(typescript@5.8.2)(yaml@2.7.0)
|
||||||
|
astro-og-canvas:
|
||||||
|
specifier: ^0.7.0
|
||||||
|
version: 0.7.0(astro@5.4.3(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.28.2)(rollup@4.35.0)(terser@5.37.0)(typescript@5.8.2)(yaml@2.7.0))
|
||||||
astro-robots-txt:
|
astro-robots-txt:
|
||||||
specifier: ^1.0.0
|
specifier: ^1.0.0
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
canvaskit-wasm:
|
||||||
|
specifier: ^0.39.1
|
||||||
|
version: 0.39.1
|
||||||
hastscript:
|
hastscript:
|
||||||
specifier: ^9.0.1
|
specifier: ^9.0.1
|
||||||
version: 9.0.1
|
version: 9.0.1
|
||||||
|
@ -1173,6 +1179,9 @@ packages:
|
||||||
resolution: {integrity: sha512-K+mfUpuLilzFUN3G84ytB02v5EkaaU0eOyN6BILcSozjUpSsggbgcy73WBiuUVg8u7pRsIvx192/PclJYvaWCg==}
|
resolution: {integrity: sha512-K+mfUpuLilzFUN3G84ytB02v5EkaaU0eOyN6BILcSozjUpSsggbgcy73WBiuUVg8u7pRsIvx192/PclJYvaWCg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
'@webgpu/types@0.1.21':
|
||||||
|
resolution: {integrity: sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==}
|
||||||
|
|
||||||
acorn-jsx@5.3.2:
|
acorn-jsx@5.3.2:
|
||||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -1248,6 +1257,12 @@ packages:
|
||||||
resolution: {integrity: sha512-3oqANMjrvJ+IE5pwlUWsH/4UztmYf/GTL0HPUkWnYBNAHiGVGrOh2EbegxS5niAwlO0w9dRYk0CkCPlJcu8c3Q==}
|
resolution: {integrity: sha512-3oqANMjrvJ+IE5pwlUWsH/4UztmYf/GTL0HPUkWnYBNAHiGVGrOh2EbegxS5niAwlO0w9dRYk0CkCPlJcu8c3Q==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
|
astro-og-canvas@0.7.0:
|
||||||
|
resolution: {integrity: sha512-aamARDNDORPxXlPt+VJakzj4WpNUDjQqUZ06eE82pGMad4aTR/KMm8Ho12qvprgJcM8K7fgSOMg5OHa7KcX0pw==}
|
||||||
|
engines: {node: '>=18.14.1'}
|
||||||
|
peerDependencies:
|
||||||
|
astro: ^3.0.0 || ^4.0.0 || ^5.0.0
|
||||||
|
|
||||||
astro-robots-txt@1.0.0:
|
astro-robots-txt@1.0.0:
|
||||||
resolution: {integrity: sha512-6JQSLid4gMhoWjOm85UHLkgrw0+hHIjnJVIUqxjU2D6feKlVyYukMNYjH44ZDZBK1P8hNxd33PgWlHzCASvedA==}
|
resolution: {integrity: sha512-6JQSLid4gMhoWjOm85UHLkgrw0+hHIjnJVIUqxjU2D6feKlVyYukMNYjH44ZDZBK1P8hNxd33PgWlHzCASvedA==}
|
||||||
|
|
||||||
|
@ -1329,6 +1344,9 @@ packages:
|
||||||
caniuse-lite@1.0.30001703:
|
caniuse-lite@1.0.30001703:
|
||||||
resolution: {integrity: sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==}
|
resolution: {integrity: sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==}
|
||||||
|
|
||||||
|
canvaskit-wasm@0.39.1:
|
||||||
|
resolution: {integrity: sha512-Gy3lCmhUdKq+8bvDrs9t8+qf7RvcjuQn+we7vTVVyqgOVO1UVfHpsnBxkTZw+R4ApEJ3D5fKySl9TU11hmjl/A==}
|
||||||
|
|
||||||
ccount@2.0.1:
|
ccount@2.0.1:
|
||||||
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
||||||
|
|
||||||
|
@ -4920,6 +4938,8 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
|
'@webgpu/types@0.1.21': {}
|
||||||
|
|
||||||
acorn-jsx@5.3.2(acorn@8.14.1):
|
acorn-jsx@5.3.2(acorn@8.14.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
acorn: 8.14.1
|
acorn: 8.14.1
|
||||||
|
@ -5042,6 +5062,13 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
astro-og-canvas@0.7.0(astro@5.4.3(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.28.2)(rollup@4.35.0)(terser@5.37.0)(typescript@5.8.2)(yaml@2.7.0)):
|
||||||
|
dependencies:
|
||||||
|
astro: 5.4.3(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.28.2)(rollup@4.35.0)(terser@5.37.0)(typescript@5.8.2)(yaml@2.7.0)
|
||||||
|
canvaskit-wasm: 0.39.1
|
||||||
|
deterministic-object-hash: 2.0.2
|
||||||
|
entities: 4.5.0
|
||||||
|
|
||||||
astro-robots-txt@1.0.0:
|
astro-robots-txt@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
valid-filename: 4.0.0
|
valid-filename: 4.0.0
|
||||||
|
@ -5210,6 +5237,10 @@ snapshots:
|
||||||
|
|
||||||
caniuse-lite@1.0.30001703: {}
|
caniuse-lite@1.0.30001703: {}
|
||||||
|
|
||||||
|
canvaskit-wasm@0.39.1:
|
||||||
|
dependencies:
|
||||||
|
'@webgpu/types': 0.1.21
|
||||||
|
|
||||||
ccount@2.0.1: {}
|
ccount@2.0.1: {}
|
||||||
|
|
||||||
chalk@4.1.2:
|
chalk@4.1.2:
|
||||||
|
|
|
@ -2,26 +2,22 @@ import { defineCollection, z } from 'astro:content'
|
||||||
|
|
||||||
const postsCollection = defineCollection({
|
const postsCollection = defineCollection({
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
|
// required
|
||||||
// Basic
|
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
published: z.date(),
|
published: z.date(),
|
||||||
|
// optional
|
||||||
updated: z.date().optional(),
|
updated: z.date().optional(),
|
||||||
|
description: z.string().optional().default(''),
|
||||||
tags: z.array(z.string()).optional().default([]),
|
tags: z.array(z.string()).optional().default([]),
|
||||||
|
|
||||||
// Advanced
|
// Advanced
|
||||||
pin: z.number().int().min(0).max(99).optional().default(0),
|
|
||||||
draft: z.boolean().optional().default(false),
|
draft: z.boolean().optional().default(false),
|
||||||
|
pin: z.number().int().min(0).max(99).optional().default(0),
|
||||||
toc: z.boolean().optional().default(false),
|
toc: z.boolean().optional().default(false),
|
||||||
lang: z.string().optional().default(''),
|
lang: z.string().optional().default(''),
|
||||||
abbrlink: z.string().optional().default('').refine(
|
abbrlink: z.string().optional().default('').refine(
|
||||||
abbrlink => !abbrlink || /^[a-z0-9\-]*$/.test(abbrlink),
|
abbrlink => !abbrlink || /^[a-z0-9\-]*$/.test(abbrlink),
|
||||||
{ message: 'Abbrlink can only contain lowercase letters, numbers and hyphens' },
|
{ message: 'Abbrlink can only contain lowercase letters, numbers and hyphens' },
|
||||||
),
|
),
|
||||||
|
|
||||||
// Auto-generated
|
|
||||||
description: z.string().optional().default(''),
|
|
||||||
image: z.string().optional().default(''),
|
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
---
|
---
|
||||||
import themeConfig from '@/config'
|
import themeConfig from '@/config'
|
||||||
|
import { isPostPage } from '@/utils/path'
|
||||||
import { ClientRouter } from 'astro:transitions'
|
import { ClientRouter } from 'astro:transitions'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
postTitle?: string
|
postTitle?: string
|
||||||
postDescription?: string
|
postDescription?: string
|
||||||
postImage?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { postTitle, postDescription, postImage } = Astro.props
|
const { postTitle, postDescription } = Astro.props
|
||||||
|
|
||||||
const { title, subtitle, description, author, url, favicon } = themeConfig.site
|
const { title, subtitle, description, author, url, favicon } = themeConfig.site
|
||||||
const { mode, light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
const { mode, light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
||||||
|
@ -20,7 +20,18 @@ const { commentURL = '', imageHostURL = '', customGoogleAnalyticsJS = '', custom
|
||||||
const initMetaTheme = mode === 'dark' ? darkMode : lightMode
|
const initMetaTheme = mode === 'dark' ? darkMode : lightMode
|
||||||
const pageTitle = postTitle ? `${postTitle} | ${title}` : `${title} - ${subtitle}`
|
const pageTitle = postTitle ? `${postTitle} | ${title}` : `${title} - ${subtitle}`
|
||||||
const pageDescription = postDescription || description
|
const pageDescription = postDescription || description
|
||||||
const pageImage = postImage || favicon
|
|
||||||
|
// Determine the OG image for the page
|
||||||
|
// Check if the current page is a post
|
||||||
|
const currentPath = Astro.url.pathname
|
||||||
|
const isPost = isPostPage(currentPath)
|
||||||
|
|
||||||
|
// Extract slug from URL as the post identifier
|
||||||
|
const pathParts = currentPath.split('/').filter(part => part !== '')
|
||||||
|
const slug = pathParts.length > 0 ? pathParts[pathParts.length - 1] : ''
|
||||||
|
|
||||||
|
// Prioritize auto-generated OG image, otherwise use fallback OG image
|
||||||
|
const pageImage = isPost && slug ? `${url}/og/${slug}` : favicon
|
||||||
---
|
---
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
|
|
@ -18,10 +18,9 @@ import '@/styles/heti.css'
|
||||||
interface Props {
|
interface Props {
|
||||||
postTitle?: string
|
postTitle?: string
|
||||||
postDescription?: string
|
postDescription?: string
|
||||||
postImage?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { postTitle, postDescription, postImage } = Astro.props
|
const { postTitle, postDescription } = Astro.props
|
||||||
const { isHome, isPost } = getPagePath(Astro.url.pathname)
|
const { isHome, isPost } = getPagePath(Astro.url.pathname)
|
||||||
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
|
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
|
||||||
|
|
||||||
|
@ -35,7 +34,7 @@ const footerMarginClass = isPost && themeConfig.comment?.waline?.serverURL
|
||||||
class={fontStyle}
|
class={fontStyle}
|
||||||
data-overlayscrollbars-initialize
|
data-overlayscrollbars-initialize
|
||||||
>
|
>
|
||||||
<Head {postTitle} {postDescription} {postImage} />
|
<Head {postTitle} {postDescription} />
|
||||||
<body data-overlayscrollbars-initialize>
|
<body data-overlayscrollbars-initialize>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<div
|
<div
|
||||||
|
|
28
src/pages/og/[...route].ts
Normal file
28
src/pages/og/[...route].ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { OGImageRoute } from 'astro-og-canvas'
|
||||||
|
import { getCollection } from 'astro:content'
|
||||||
|
|
||||||
|
// eslint-disable-next-line antfu/no-top-level-await
|
||||||
|
const blogEntries = await getCollection('posts')
|
||||||
|
|
||||||
|
// Convert to page data objects
|
||||||
|
const pages = Object.fromEntries(
|
||||||
|
blogEntries.map(({ slug, data }) => [
|
||||||
|
data.abbrlink || slug, // Prioritize using abbrlink instead of slug
|
||||||
|
{
|
||||||
|
title: data.title,
|
||||||
|
description: data.description || '',
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Configure Open Graph image generation route
|
||||||
|
export const { getStaticPaths, GET } = OGImageRoute({
|
||||||
|
param: 'route',
|
||||||
|
pages,
|
||||||
|
getImageOptions: (_path, page) => ({
|
||||||
|
title: page.title,
|
||||||
|
description: page.description,
|
||||||
|
border: { width: 10 },
|
||||||
|
padding: 40,
|
||||||
|
}),
|
||||||
|
})
|
|
@ -26,7 +26,6 @@ const { Content, remarkPluginFrontmatter } = await post.render()
|
||||||
<Layout
|
<Layout
|
||||||
postTitle={post.data.title}
|
postTitle={post.data.title}
|
||||||
postDescription={description}
|
postDescription={description}
|
||||||
postImage={post.data.image}
|
|
||||||
>
|
>
|
||||||
<article class="heti mb-12.6">
|
<article class="heti mb-12.6">
|
||||||
<h1 class="post-title">
|
<h1 class="post-title">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue