Skip to content

Commit edf0651

Browse files
authored
fix(nx-dev): OG image meta tag (nrwl#27195)
1 parent adbb861 commit edf0651

File tree

4 files changed

+62
-8
lines changed

4 files changed

+62
-8
lines changed

nx-dev/data-access-documents/src/lib/blog.api.ts

+55-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { readFileSync, readdirSync } from 'fs';
2-
import { join, basename } from 'path';
1+
import { readFileSync, readdirSync, accessSync, constants } from 'fs';
2+
import { join, basename, parse, resolve } from 'path';
33
import { extractFrontmatter } from '@nx/nx-dev/ui-markdoc';
44
import { sortPosts } from './blog.util';
55
import { BlogPostDataEntry } from './blog.model';
@@ -42,6 +42,8 @@ export class BlogApi {
4242
const content = await readFile(filePath, 'utf8');
4343
const frontmatter = extractFrontmatter(content);
4444
const slug = this.calculateSlug(filePath, frontmatter);
45+
const { image, type } = this.determineOgImage(frontmatter.cover_image);
46+
4547
const post = {
4648
content,
4749
title: frontmatter.title ?? null,
@@ -56,6 +58,8 @@ export class BlogApi {
5658
tags: frontmatter.tags ?? [],
5759
reposts: frontmatter.reposts ?? [],
5860
pinned: frontmatter.pinned ?? false,
61+
ogImage: image,
62+
ogImageType: type,
5963
filePath,
6064
slug,
6165
};
@@ -81,6 +85,7 @@ export class BlogApi {
8185
const content = readFileSync(filePath, 'utf8');
8286
const frontmatter = extractFrontmatter(content);
8387
const slug = this.calculateSlug(filePath, frontmatter);
88+
const { image, type } = this.determineOgImage(frontmatter.cover_image);
8489
const post = {
8590
content,
8691
title: frontmatter.title ?? null,
@@ -95,6 +100,8 @@ export class BlogApi {
95100
tags: frontmatter.tags ?? [],
96101
reposts: frontmatter.reposts ?? [],
97102
pinned: frontmatter.pinned ?? false,
103+
ogImage: image,
104+
ogImageType: type,
98105
filePath,
99106
slug,
100107
};
@@ -143,4 +150,50 @@ export class BlogApi {
143150
}
144151
}
145152
}
153+
154+
private fileExists(filePath: string): boolean {
155+
try {
156+
accessSync(filePath, constants.F_OK);
157+
return true;
158+
} catch (error) {
159+
return false;
160+
}
161+
}
162+
163+
private determineOgImage(imagePath: string): {
164+
image: string;
165+
type: string;
166+
} {
167+
const allowedExtensions = ['.png', '.webp', '.jpg', '.jpeg'];
168+
const defaultImage = 'https://nx.dev/socials/nx-media.png';
169+
const defaultType = 'png';
170+
171+
if (!imagePath) {
172+
return { image: defaultImage, type: defaultType };
173+
}
174+
const { ext } = parse(imagePath);
175+
176+
if (!allowedExtensions.includes(ext)) {
177+
const foundExt = allowedExtensions.find((allowedExt) => {
178+
const ogImagePath = imagePath.replace(ext, allowedExt);
179+
return this.fileExists(
180+
join(
181+
'public',
182+
'documentation',
183+
resolve(this.options.blogRoot, ogImagePath)
184+
)
185+
);
186+
});
187+
188+
if (!foundExt) {
189+
return { image: defaultImage, type: defaultType };
190+
}
191+
192+
return {
193+
image: imagePath.replace(ext, foundExt),
194+
type: foundExt.replace('.', ''),
195+
};
196+
}
197+
return { image: imagePath, type: ext.replace('.', '') };
198+
}
146199
}

nx-dev/data-access-documents/src/lib/blog.model.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export type BlogPostDataEntry = {
1111
pinned?: boolean;
1212
filePath: string;
1313
slug: string;
14+
ogImage: string;
15+
ogImageType: string;
1416
};
1517

1618
export type BlogAuthor = {

nx-dev/data-access-documents/src/lib/blog.util.spec.ts

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ function createPost(data: {
6262
title: data.title,
6363
description: '',
6464
authors: [],
65+
ogImage: '',
66+
ogImageType: '',
6567
cover_image: '',
6668
tags: [],
6769
reposts: [],

nx-dev/nx-dev/app/blog/[slug]/page.tsx

+3-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Metadata, ResolvingMetadata } from 'next';
22
import { blogApi } from '../../../lib/blog.api';
33
import { BlogDetails } from '@nx/nx-dev/ui-blog';
44
import { DefaultLayout } from '@nx/nx-dev/ui-common';
5-
import { parse } from 'path';
5+
66
interface BlogPostDetailProps {
77
params: { slug: string };
88
}
@@ -14,9 +14,6 @@ export async function generateMetadata(
1414
const post = await blogApi.getBlogPostBySlug(slug);
1515
const previousImages = (await parent).openGraph?.images ?? [];
1616

17-
const postCoverImage = post?.cover_image || 'nx-media';
18-
const ogImage = `${parse(postCoverImage).name}.png`;
19-
2017
return {
2118
title: `${post.title} | Nx Blog`,
2219
description: 'Latest news from the Nx & Nx Cloud core team',
@@ -26,11 +23,11 @@ export async function generateMetadata(
2623
description: post.description,
2724
images: [
2825
{
29-
url: ogImage,
26+
url: post.ogImage,
3027
width: 800,
3128
height: 421,
3229
alt: 'Nx: Smart, Fast and Extensible Build System',
33-
type: 'image/png',
30+
type: `image/${post.ogImageType}`,
3431
},
3532
...previousImages,
3633
],

0 commit comments

Comments
 (0)