adding alternative language versions to article metadata
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import { MDXRemote } from "next-mdx-remote/rsc";
|
||||
import { getArticleBySlug, getAllArticles } from "@/lib/blog/get-articles";
|
||||
import { getArticleBySlug, getAllArticles, getAlternatesArticle } from "@/lib/blog/get-articles";
|
||||
import { ArticleHero } from "@/components/sections/ArticleHero";
|
||||
import { ArticleSummary } from "@/components/sections/ArticleSummary";
|
||||
import { locales } from "@/middleware";
|
||||
@@ -24,6 +24,14 @@ export async function generateMetadata({ params }: props): Promise<Metadata> {
|
||||
return {};
|
||||
}
|
||||
|
||||
const languageAlternates = getAlternatesArticle(article);
|
||||
const absoluteLanguageAlternates = Object.fromEntries(
|
||||
Object.entries(languageAlternates).map(([language, path]) => [
|
||||
language,
|
||||
`${siteUrl}${path}`,
|
||||
])
|
||||
);
|
||||
|
||||
const url = `${siteUrl}/${locale}/blog/${slug}`;
|
||||
const title = article.title;
|
||||
const description = article.description;
|
||||
@@ -38,6 +46,10 @@ export async function generateMetadata({ params }: props): Promise<Metadata> {
|
||||
description,
|
||||
alternates: {
|
||||
canonical: url,
|
||||
languages: {
|
||||
...absoluteLanguageAlternates,
|
||||
"x-default": url,
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
ready: true
|
||||
translationKey: "how-I-built-my-new-website"
|
||||
title: "How I built my new website, and why ?"
|
||||
description: "Discover how I built my website, the origin of this need, and the steps I went through."
|
||||
date: "2026-04-17"
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
---
|
||||
ready: true
|
||||
translationKey: "claude-design-vs-figma-make"
|
||||
title: "Claude Design vs. Figma Make: How I Combined the Two to Optimize My Prototyping"
|
||||
description: A comparison of the two tools and how I used them
|
||||
date: 2026-04-30
|
||||
category: Technologies
|
||||
description: "A comparison of the two tools and how I used them"
|
||||
date: "2026-04-30"
|
||||
category: "Technologies"
|
||||
tags:
|
||||
- Design
|
||||
- AI
|
||||
- Experience
|
||||
- Comparison
|
||||
- Technologies
|
||||
readTime: 5 min
|
||||
- "Design"
|
||||
- "AI"
|
||||
- "Experience"
|
||||
- "Comparison"
|
||||
- "Technologies"
|
||||
readTime: "5 min"
|
||||
summary:
|
||||
- The Arrival of Claude Design
|
||||
- "The Arrival of Claude Design"
|
||||
- "The Flip Side: A Restrictive Pricing Model"
|
||||
- "The Alternative: Figma Make"
|
||||
- "The Ideal Workflow: Making Claude and Figma Talk"
|
||||
- Epilogue
|
||||
- "Epilogue"
|
||||
---
|
||||
## The Arrival of Claude Design
|
||||
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
---
|
||||
ready: true
|
||||
title: Comment j'ai construit mon nouveau site internet, et pourquoi ?
|
||||
description: Découvrez comment j'ai construit mon site, l'origine de ce besoin et les étapes par lesquelles je suis passé.
|
||||
date: 2026-04-17
|
||||
category: Développement Web
|
||||
translationKey: "how-I-built-my-new-website"
|
||||
title: "Comment j'ai construit mon nouveau site internet, et pourquoi ?"
|
||||
description: "Découvrez comment j'ai construit mon site, l'origine de ce besoin et les étapes par lesquelles je suis passé."
|
||||
date: "2026-04-17"
|
||||
category: "Développement Web"
|
||||
tags:
|
||||
- Portfolio
|
||||
- Design
|
||||
- Apprentissage
|
||||
readTime: 5 min
|
||||
- "Portfolio"
|
||||
- "Design"
|
||||
- "Apprentissage"
|
||||
readTime: "5 min"
|
||||
summary:
|
||||
- Pourquoi maintenant et pas des années plus tôt ?
|
||||
- "Pourquoi maintenant et pas des années plus tôt ?"
|
||||
- "Le plus long : maquette Figma"
|
||||
- Comment et avec quoi ? La stack de rêve
|
||||
- Mon terrain de jeu personnel
|
||||
- "Comment et avec quoi ? La stack de rêve"
|
||||
- "Mon terrain de jeu personnel"
|
||||
---
|
||||
|
||||
## Pourquoi maintenant et pas des années plus tôt ?
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
---
|
||||
ready: true
|
||||
translationKey: "claude-design-vs-figma-make"
|
||||
title: "Claude Design face à Figma Make : Comment j'ai combiné les deux pour optimiser mon prototypage"
|
||||
description: Comparatif des deux outils et comment je m'en suis servie
|
||||
date: 2026-04-30
|
||||
category: Technologies
|
||||
description: "Comparatif des deux outils et comment je m'en suis servie"
|
||||
date: "2026-04-30"
|
||||
category: "Technologies"
|
||||
tags:
|
||||
- Design
|
||||
- IA
|
||||
- Expérience
|
||||
- Comparatif
|
||||
- Technologies
|
||||
readTime: 5 min
|
||||
- "Design"
|
||||
- "IA"
|
||||
- "Expérience"
|
||||
- "Comparatif"
|
||||
- "Technologies"
|
||||
readTime: "5 min"
|
||||
summary:
|
||||
- L'arrivée de Claude Design
|
||||
- "L'arrivée de Claude Design"
|
||||
- "Le revers de la médaille : un modèle économique contraignant"
|
||||
- "L'alternative : Figma Make"
|
||||
- "Le workflow idéal : faire dialoguer Claude et Figma"
|
||||
- Épilogue
|
||||
- "Épilogue"
|
||||
---
|
||||
## L'arrivée de Claude Design
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import matter from "gray-matter";
|
||||
import { locales } from "@/middleware";
|
||||
|
||||
import { Article, ArticleFrontmatter } from "./types";
|
||||
|
||||
const CONTENT_DIR = path.join(process.cwd(), "content/blog");
|
||||
@@ -42,3 +44,22 @@ export function getAllArticles(locale: string): Article[] {
|
||||
.filter((article): article is Article => article !== null && article.ready)
|
||||
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
||||
}
|
||||
|
||||
export function getAlternatesArticle(article: Article) {
|
||||
if (!article.translationKey) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return locales.reduce<Record<string, string>>((acc, locale) => {
|
||||
const translatedArticle = getAllArticles(locale).find(
|
||||
(candidate) =>
|
||||
candidate.translationKey === article.translationKey
|
||||
);
|
||||
|
||||
if (translatedArticle) {
|
||||
acc[locale] = `/${locale}/blog/${translatedArticle.slug}`;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
export type ArticleFrontmatter = {
|
||||
ready: boolean;
|
||||
translationKey: string;
|
||||
title: string;
|
||||
description: string;
|
||||
date: string;
|
||||
|
||||
Reference in New Issue
Block a user