diff --git a/astro.config.mjs b/astro.config.mjs index 1b024d4..aadfeee 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -4,6 +4,7 @@ import mdx from "@astrojs/mdx"; import tailwindcss from "@tailwindcss/vite"; import icon from "astro-icon"; import remarkReadingTime from "remark-reading-time"; +import { remarkR2Images } from './src/plugins/remark-r2-images.mjs'; export default defineConfig({ site: "https://balodeplao.com/", @@ -17,6 +18,7 @@ export default defineConfig({ file.data.readingTime.minutes; }; }, + remarkR2Images ], }, i18n: { diff --git a/package-lock.json b/package-lock.json index 43f9e87..81466b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,8 @@ "astro-icon": "^1.1.5", "remark-reading-time": "^2.0.2", "tailwindcss": "^4.1.18", - "typescript": "^5.9.3" + "typescript": "^5.9.3", + "unist-util-visit": "^5.1.0" }, "devDependencies": { "@tailwindcss/typography": "^0.5.19", @@ -1249,9 +1250,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1268,9 +1266,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1287,9 +1282,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1306,9 +1298,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1325,9 +1314,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1344,9 +1330,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1363,9 +1346,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1382,9 +1362,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1401,9 +1378,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1426,9 +1400,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1451,9 +1422,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1476,9 +1444,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1501,9 +1466,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1526,9 +1488,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1551,9 +1510,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1576,9 +1532,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ diff --git a/package.json b/package.json index 2bbaa3c..1e95ad8 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "astro-icon": "^1.1.5", "remark-reading-time": "^2.0.2", "tailwindcss": "^4.1.18", - "typescript": "^5.9.3" + "typescript": "^5.9.3", + "unist-util-visit": "^5.1.0" }, "devDependencies": { "@tailwindcss/typography": "^0.5.19", diff --git a/src/components/blog/PostItem.astro b/src/components/blog/PostItem.astro index 96c3f80..25eb474 100644 --- a/src/components/blog/PostItem.astro +++ b/src/components/blog/PostItem.astro @@ -2,6 +2,7 @@ import Tags from "@/components/ui/Tags.astro"; import Categories from "@/components/ui/Categories.astro"; import { type CollectionEntry, render } from "astro:content"; +import { toR2Url } from "@/utils/r2"; export interface Props { post: CollectionEntry<"blog">; @@ -9,6 +10,7 @@ export interface Props { const { post } = Astro.props; const { remarkPluginFrontmatter } = await render(post); +const coverImage = toR2Url(post.data.image); const readingTime = remarkPluginFrontmatter?.minutesRead ? `${Math.ceil(remarkPluginFrontmatter.minutesRead)} phút đọc` @@ -20,9 +22,9 @@ const readingTime = remarkPluginFrontmatter?.minutesRead >
{ - post.data.image && ( + coverImage && ( {post.data.title} diff --git a/src/config/r2.mjs b/src/config/r2.mjs new file mode 100644 index 0000000..c5550d2 --- /dev/null +++ b/src/config/r2.mjs @@ -0,0 +1 @@ +export const R2_BASE = 'https://media.balodeplao.com'; diff --git a/src/pages/[...slug].astro b/src/pages/[...slug].astro index 1965de8..2b5fd39 100644 --- a/src/pages/[...slug].astro +++ b/src/pages/[...slug].astro @@ -3,6 +3,7 @@ import BaseLayout from "@/layouts/BaseLayout.astro"; import Schema from "@/components/seo/Schema.astro"; import Tags from "@/components/ui/Tags.astro"; import Categories from "@/components/ui/Categories.astro"; +import { toR2Url } from "@/utils/r2"; import { getCollection, render } from "astro:content"; @@ -18,6 +19,7 @@ const { post } = Astro.props; const { Content, remarkPluginFrontmatter } = await render(post); const { title, description, pubDate, author, image, categories, tags } = post.data; +const coverImage = toR2Url(image); const formattedDate = pubDate.toLocaleDateString("vi-VN", { year: "numeric", @@ -32,7 +34,7 @@ const readingTime = remarkPluginFrontmatter?.minutesRead const metadata = { title: title, description: description, - ogImage: image, + ogImage: coverImage, }; --- @@ -70,9 +72,13 @@ const metadata = {
{ - image && ( + coverImage && (
- {title} + {title}
) } diff --git a/src/plugins/remark-r2-images.mjs b/src/plugins/remark-r2-images.mjs new file mode 100644 index 0000000..182899e --- /dev/null +++ b/src/plugins/remark-r2-images.mjs @@ -0,0 +1,19 @@ +import { visit } from 'unist-util-visit'; +import { R2_BASE } from '../config/r2.mjs'; + +export function remarkR2Images() { + return (tree) => { + visit(tree, 'image', (node) => { + if (node.url.startsWith('/images/')) { + node.url = `${R2_BASE}${node.url}`; + } + }); + + visit(tree, 'html', (node) => { + node.value = node.value.replace( + /src="(\/images\/[^"]+)"/g, + `src="${R2_BASE}$1"` + ); + }); + }; +} diff --git a/src/utils/r2.ts b/src/utils/r2.ts new file mode 100644 index 0000000..0282718 --- /dev/null +++ b/src/utils/r2.ts @@ -0,0 +1,7 @@ +import { R2_BASE } from "@/config/r2.mjs"; + +export function toR2Url(path?: string): string | undefined { + if (!path) return undefined; + if (path.startsWith("http")) return path; + return `${R2_BASE}${path}`; +}