From d99f826c8b1a61170cb5c46d00775ee583472172 Mon Sep 17 00:00:00 2001 From: nemanjam Date: Fri, 12 Jul 2024 21:40:30 +0200 Subject: [PATCH] fix static paths for mdx and list pages --- docs/working-notes/todo3.md | 3 ++ src/constants/metadata.ts | 3 ++ src/layouts/Page.astro | 5 ++- src/libs/api/open-graph/pages.ts | 3 +- src/libs/api/open-graph/template-html.ts | 9 ++-- src/pages/api/open-graph/[...route].png.ts | 2 +- src/types/utils.ts | 5 +++ src/utils/open-graph-image.ts | 50 ++++++++++++++++------ src/utils/paths.ts | 2 + 9 files changed, 63 insertions(+), 19 deletions(-) diff --git a/docs/working-notes/todo3.md b/docs/working-notes/todo3.md index 8e89bfb..9704215 100644 --- a/docs/working-notes/todo3.md +++ b/docs/working-notes/todo3.md @@ -396,5 +396,8 @@ satori can define og image with html, astro-canvas limited satori understands only react jsx, not solid-js solid-js style prop dash case 'border-radius': '3px' use satori vercel playground for design og image and research examples +og image getStaticPath paths +handle long site url in og template +add random hero images for mdx and list pages, and maybe random gradient, handle longer domain in new row ``` diff --git a/src/constants/metadata.ts b/src/constants/metadata.ts index f09b8e9..8c409ef 100644 --- a/src/constants/metadata.ts +++ b/src/constants/metadata.ts @@ -1,6 +1,7 @@ import { CONFIG } from '@/config'; import type { Metadata } from '@/types/common'; +import type { ValueUnion } from '@/types/utils'; // can't import getDefaultOpenGraphImagePath here, circular dependency @@ -57,3 +58,5 @@ export const OG_IMAGE_PREFIXES = { OG_PAGES: 'pages', OG_LISTS: 'lists', } as const; + +export type OgImagePrefixType = ValueUnion; diff --git a/src/layouts/Page.astro b/src/layouts/Page.astro index 4a4c748..1269104 100644 --- a/src/layouts/Page.astro +++ b/src/layouts/Page.astro @@ -22,7 +22,10 @@ const { title, description } = content; const { pathname } = Astro.url; // og image for metadata, only call in layouts -const path = `/pages${pathname}`; + +//! important: fix home page path '/' for og image here, not in getStaticPathsv or getOpenGraphImagePath() +const path = ['', '/'].includes(pathname) ? '/pages/index' : `/pages${pathname}`; + const image = getOpenGraphImagePath(path); const metadata = { title, description, image }; diff --git a/src/libs/api/open-graph/pages.ts b/src/libs/api/open-graph/pages.ts index 22d55ed..adeb83e 100644 --- a/src/libs/api/open-graph/pages.ts +++ b/src/libs/api/open-graph/pages.ts @@ -45,8 +45,7 @@ export const getPages = async () => { allProjects.map((project) => [`${OG_IMAGE_PREFIXES.OG_PROJECTS}/${project.slug}`, project.data]) ); - // const pages = { ...posts, ...projects, ...mdxPages, ...listPages }; - const pages = { ...posts, ...projects }; + const pages = { ...posts, ...projects, ...mdxPages, ...listPages }; return pages; }; diff --git a/src/libs/api/open-graph/template-html.ts b/src/libs/api/open-graph/template-html.ts index 638e1dc..e19ffb9 100644 --- a/src/libs/api/open-graph/template-html.ts +++ b/src/libs/api/open-graph/template-html.ts @@ -9,10 +9,13 @@ export interface TemplateProps { const templateHtml = ({ title, heroImageUrl, avatarImageUrl, siteUrl }: TemplateProps) => html`
-
+
-
-
${title}
+
+ +
${title}
+ +
{ // object to array of tuples const paths = Object.entries(pages).map(([path, page]) => ({ - params: { route: path }, + params: { route: path }, // home page '/' path fixed to '/page/index/ in src/layouts/Page.astro props: { page }, })); diff --git a/src/types/utils.ts b/src/types/utils.ts index c8ee801..7630ffa 100644 --- a/src/types/utils.ts +++ b/src/types/utils.ts @@ -3,3 +3,8 @@ * Unused, use ComponentProps instead. */ export type InferProps = T extends (props: infer P) => JSX.Element ? P : never; + +/** + * Extracts the union type of values from a constant object. + */ +export type ValueUnion> = T[keyof T]; diff --git a/src/utils/open-graph-image.ts b/src/utils/open-graph-image.ts index f5d9c51..7f503f0 100644 --- a/src/utils/open-graph-image.ts +++ b/src/utils/open-graph-image.ts @@ -1,15 +1,23 @@ import { OG_IMAGE_PREFIXES } from '@/constants/metadata'; import { ROUTES } from '@/constants/routes'; -import { removeLeadingAndTrailingSlashes } from '@/utils/paths'; +import { removeFirstPathSegment, removeLeadingAndTrailingSlashes } from '@/utils/paths'; + +import type { OgImagePrefixType } from '@/constants/metadata'; /*--------------------- getOpenGraphImagePath -------------------*/ -const { OG_PAGES } = OG_IMAGE_PREFIXES; +export const getOpenGraphImagePath = (path: string): string => { + // only to throw for invalid path + const _prefix = getPagePrefix(path); -const homePageOgImage = `${ROUTES.API.OG_IMAGES}${OG_PAGES}.png`; -const _404PageOgImage = `${ROUTES.API.OG_IMAGES}${OG_PAGES}404.png`; + const trimmedPath = removeLeadingAndTrailingSlashes(path); -export const getOpenGraphImagePath = (path: string): string => { + const imagePath = `${ROUTES.API.OG_IMAGES}${trimmedPath}.png`; + + return imagePath; +}; + +export const getPagePrefix = (path: string): OgImagePrefixType => { const trimmedPath = removeLeadingAndTrailingSlashes(path); let prefix = trimmedPath.split('/')[0]; @@ -19,15 +27,33 @@ export const getOpenGraphImagePath = (path: string): string => { const prefixes = Object.values(OG_IMAGE_PREFIXES) as string[]; if (!prefixes.includes(prefix)) { - console.error(`Unknown path prefix requested: ${prefix}`); - return _404PageOgImage; + const message = `Unknown path prefix requested: ${prefix}`; + console.error(message); + throw new Error(message); } - // prevents recursion on 404 - // if (prefix === 'pages' && !isKnownRoute(trimmedPath)) return _404PageOgImage; // about -> pages/about - if (trimmedPath === '') return homePageOgImage; + return prefix as OgImagePrefixType; +}; - const imagePath = `${ROUTES.API.OG_IMAGES}${trimmedPath}.png`; +/** not needed function, wrong */ +export const getPathForGetStaticPaths = (path: string): string => { + const prefix = getPagePrefix(path); - return imagePath; + let staticPath: string; + + switch (prefix) { + case OG_IMAGE_PREFIXES.OG_BLOG: + case OG_IMAGE_PREFIXES.OG_PROJECTS: + staticPath = path; + break; + case OG_IMAGE_PREFIXES.OG_PAGES: + case OG_IMAGE_PREFIXES.OG_LISTS: + staticPath = removeFirstPathSegment(path); + break; + + default: + throw new Error(`Unknown static path prefix requested: ${prefix}`); + } + + return staticPath; }; diff --git a/src/utils/paths.ts b/src/utils/paths.ts index 11c2c83..918c23e 100644 --- a/src/utils/paths.ts +++ b/src/utils/paths.ts @@ -10,6 +10,8 @@ export const removeTrailingSlash = (path: string) => path.replace(/\/+$/g, ''); export const removeLeadingAndTrailingSlashes = (path: string) => path.replace(/^\/+|\/+$/g, ''); +export const removeFirstPathSegment = (path: string) => path.split('/').slice(1).join('/'); + /*----------------------------- detect unknown routes ---------------------------*/ // maybe remove