Skip to content

Commit 989b438

Browse files
committed
feat: add og:image to projects
1 parent 053e496 commit 989b438

1 file changed

Lines changed: 84 additions & 15 deletions

File tree

src/pages/projects.astro

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,50 @@
11
---
22
import BaseLayout from '../layouts/BaseLayout.astro'
33
4-
const projects = [
4+
async function fetchMetaTags(url: string) {
5+
try {
6+
const response = await fetch(url)
7+
const html = await response.text()
8+
9+
const titleMatch = html.match(/<meta property="og:title" content="([^"]*)"/) ||
10+
html.match(/<title[^>]*>([^<]+)<\/title>/)
11+
const descriptionMatch = html.match(/<meta property="og:description" content="([^"]*)"/) ||
12+
html.match(/<meta name="description" content="([^"]*)"/)
13+
const imageMatch = html.match(/<meta property="og:image" content="([^"]*)"/)
14+
15+
return {
16+
title: titleMatch ? titleMatch[1] : '',
17+
description: descriptionMatch ? descriptionMatch[1] : '',
18+
image: imageMatch ? imageMatch[1] : ''
19+
}
20+
} catch (error) {
21+
return { title: '', description: '', image: '' }
22+
}
23+
}
24+
25+
const projectsData = [
526
{
627
title: "shadecn",
728
description: "SVG color customizer that transforms unDraw illustrations to match your shadcn themes",
829
tech: ["React", "TypeScript", "shadcn/ui", "Tailwind CSS"],
930
github: "https://github.com/johanwulf/shadecn",
10-
live: "https://wulf.gg/shadecn"
31+
live: "https://wulf.gg/shadecn",
32+
richMediaUrl: "https://wulf.gg/shadecn"
1133
},
1234
{
1335
title: "wulf.gg",
1436
description: "This website - built with Astro, React, TypeScript, and MDX",
1537
tech: ["Astro", "TypeScript", "Tailwind CSS", "MDX"],
16-
github: "https://github.com/johanwulf/johanwulf.github.io"
38+
github: "https://github.com/johanwulf/johanwulf.github.io",
39+
richMediaUrl: "https://wulf.gg"
40+
},
41+
{
42+
title: "replace-comment",
43+
description: "GitHub Action to replace comments in PRs and issues with updated content",
44+
tech: ["TypeScript", "GitHub Actions"],
45+
github: "https://github.com/johanwulf/replace-comment",
46+
live: "https://github.com/marketplace/actions/replace-comment",
47+
richMediaUrl: "https://github.com/marketplace/actions/replace-comment"
1748
},
1849
{
1950
title: ".dotfiles",
@@ -22,25 +53,63 @@ const projects = [
2253
github: "https://github.com/johanwulf/.dotfiles"
2354
},
2455
]
56+
57+
const projects = await Promise.all(
58+
projectsData.map(async (project) => {
59+
if (project.richMediaUrl) {
60+
const metaTags = await fetchMetaTags(project.richMediaUrl)
61+
return {
62+
...project,
63+
richMedia: {
64+
url: project.richMediaUrl,
65+
...metaTags
66+
}
67+
}
68+
}
69+
return project
70+
})
71+
)
2572
---
2673

2774
<BaseLayout title="Projects - Johan Wulf">
2875
<h1 class="text-2xl font-normal mb-8">Projects</h1>
2976
<div class="space-y-8">
3077
{projects.map((project) => (
3178
<article class="pb-8 border-b border-surface-0 last:border-0">
32-
<h2 class="text-lg text-text mb-2">
33-
<span class="text-green">◆</span> {project.title}
34-
</h2>
35-
<p class="text-overlay-0 text-sm mb-3">
36-
{project.description}
37-
</p>
38-
<div class="flex flex-wrap gap-2 mb-3">
39-
{project.tech.map(tech => (
40-
<span class="text-xs px-2 py-1 bg-surface-0 text-overlay-1 rounded">
41-
{tech}
42-
</span>
43-
))}
79+
<div class="flex items-start gap-4">
80+
<div class="flex-1">
81+
<h2 class="text-lg text-text mb-2">
82+
<span class="text-green">◆</span> {project.title}
83+
</h2>
84+
<p class="text-overlay-0 text-sm mb-3">
85+
{project.description}
86+
</p>
87+
<div class="flex flex-wrap gap-2 mb-3">
88+
{project.tech.map(tech => (
89+
<span class="text-xs px-2 py-1 bg-surface-0 text-overlay-1 rounded">
90+
{tech}
91+
</span>
92+
))}
93+
</div>
94+
</div>
95+
{project.richMedia && (
96+
<div class="w-20 h-20 bg-surface-0 flex-shrink-0 flex items-center justify-center rounded-lg overflow-hidden">
97+
{project.richMedia.image ? (
98+
<img
99+
src={project.richMedia.image}
100+
alt=""
101+
class="w-full h-full object-cover"
102+
loading="lazy"
103+
/>
104+
) : (
105+
<svg class="w-6 h-6 text-overlay-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
106+
<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/>
107+
<circle cx="9" cy="9" r="2"/>
108+
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>
109+
</svg>
110+
)}
111+
</div>
112+
)}
44113
</div>
45114
<div class="text-sm text-overlay-0 space-x-4">
46115
{project.live && (

0 commit comments

Comments
 (0)