Skip to content

Commit 7d6ccdc

Browse files
committed
feat(seo): adds dynamic meta tags
1 parent b11547f commit 7d6ccdc

File tree

6 files changed

+101
-20
lines changed

6 files changed

+101
-20
lines changed

index.html

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="utf-8" />
55

66
<title>Dinh-Van Colomban | Project portfolio</title>
7-
<meta name="description" content="Dinh-Van Colomban personal website. Home of my projects, demos and portfolio." />
7+
<meta id="description" name="description" content="Dinh-Van Colomban personal website. Home of my projects, demos and portfolio." />
88

99
<!-- Google meta tags -->
1010

@@ -13,18 +13,21 @@
1313
<!-- Open Graph meta tags -->
1414

1515
<meta property="og:type" content="article" />
16-
<meta property="og:title" content="Dinh-Van Colomban | projects and experiences" />
17-
<meta property="og:description" content="Dinh-Van Colomban personal website. Home of my projects, demos and work experiences." />
18-
<meta property="og:image" content="https://dvcol.github.io/assets/png/icon.png" />
19-
<meta property="og:url" content="https://dvcol.github.io/" />
16+
<meta id="og-title" property="og:title" content="Dinh-Van Colomban | projects and experiences" />
17+
<meta id="og-description" property="og:description" content="Home of my projects, demos and portfolio." />
18+
<meta id="og-image" property="og:image" content="https://dvcol.github.io/assets/snapshot/snap.png" />
19+
<meta id="og-url" property="og:url" content="https://dvcol.github.io/" />
2020

2121
<!-- Twitter tags -->
2222

2323
<meta name="twitter:card" content="summary_large_image" />
2424
<meta name="twitter:site" content="Dinh-Van Colomban" />
25-
<meta name="twitter:title" content="Dinh-Van Colomban | projects and experiences" />
26-
<meta name="twitter:description" content="Dinh-Van Colomban personal website. Home of my projects, demos and work experiences." />
27-
<meta name="twitter:image" content="https://dvcol.github.io/assets/png/icon.png" />
25+
<meta id="tw-title" name="twitter:title" content="Dinh-Van Colomban | projects and experiences" />
26+
<meta id="tw-description" name="twitter:description" content="Home of my projects, demos and portfolio." />
27+
<meta id="tw-image" name="twitter:image" content="https://dvcol.github.io/assets/snapshot/snap.png" />
28+
29+
<meta name="twitter:creator" content="@Dinh_Van" />
30+
<meta name="twitter:site" content="@Dinh_Van" />
2831

2932
<!-- PWA tags -->
3033

public/assets/snapshot/snap.png

288 KB
Loading

src/components/common/router/route-data.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,31 @@ import type { Component } from 'solid-js';
55
import { useRouteData } from '~/services';
66
import { useI18n } from '~/services/i18n';
77

8+
const changeContent = (selector: string, content: string) => {
9+
const tag = document.head.querySelector(selector);
10+
if (!tag) return;
11+
tag.setAttribute('content', content);
12+
};
13+
814
export const RouteData: Component = () => {
915
const [t] = useI18n();
1016
createEffect(() => {
1117
const data = useRouteData().active();
12-
if (data) document.title = t(data.title);
18+
if (data?.title) {
19+
document.title = t(data.title)?.toString();
20+
changeContent('#og-title', t(data.title)?.toString());
21+
changeContent('#tw-title', t(data.title)?.toString());
22+
}
23+
if (data?.description) {
24+
changeContent('#description', t(data.description)?.toString());
25+
changeContent('#og-description', t(data.description)?.toString());
26+
changeContent('#tw-description', t(data.description)?.toString());
27+
}
28+
if (data?.image) {
29+
changeContent('#og-image', data.image);
30+
changeContent('#tw-image', data.image);
31+
}
32+
if (data?.url) changeContent('#canonical', data.url);
1333
});
1434

1535
return <div hidden aria-hidden="true" id="route-data" />;

src/i18n/models/routes.en.json

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,21 @@
2727

2828
"title": {
2929
"home": "Dinh-Van Colomban | Project portfolio",
30+
3031
"trakt": "Trakt | A chrome extension for Trakt.tv",
3132
"trakt_demo": "Trakt Demo | Interactive demo of Side Trakt",
33+
3234
"synology": "Synology | A chrome extension for Synology NAS",
3335
"synology_demo": "Synology Demo | Interactive demo of Synology Download",
34-
"syno_trakt_app": "Syno-Trakt | A react native app for Synology NAS and Trakt.tv",
35-
"syno_trakt_app_demo": "Syno-Trakt Demo | Interactive demo of Syno-Trakt",
36+
3637
"about_me": "About Me | About my projects and experiences",
3738
"contact": "Contact | Contact form",
39+
3840
"not_found": "404 | Page not Found",
3941
"unauthorized": "401 | Page unauthorized",
4042
"forbidden": "403 | Page forbidden",
4143
"error": "500 | Internal server error",
44+
4245
"particles": "Background | Animated particles",
4346
"beams": "Background | Animated beams",
4447
"redirect_to": "Redirect | Redirecting to another page",
@@ -47,8 +50,26 @@
4750
"trakt_extension": "Trakt Extension | A chrome extension for Trakt.tv",
4851
"reddit_extension": "Reddit Extension | A chrome extension for Reddit",
4952
"neo_svelte": "Neo Svelte | A neomorphic UI library for svelte 5",
50-
"svelte_simple_router": "Svelte Simple Router | A simple Svelte 5 router",
51-
"image_viewer": "Image Viewer | A simple image viewer",
52-
"syno_trakt": "Syno-Trakt | A react native app for Synology NAS and Trakt.tv"
53+
"svelte_simple_router": "Svelte Simple Router | A simple SPA router for Svelte 5",
54+
"image_viewer": "Image Viewer | A simple image viewer"
55+
},
56+
57+
"description": {
58+
"home": "Dinh-Van Colomban personal website. Home of my projects, demos and portfolio.",
59+
60+
"trakt": "A chrome extension for Trakt.tv. Keep track of your favorite TV shows and movies.",
61+
"trakt_demo": "An interactive demo for Side Trakt. A chrome extension for Trakt.tv.",
62+
63+
"synology": "A chrome extension for Synology NAS. Manage your downloads and files.",
64+
"synology_demo": "An interactive demo for Synology Download. A chrome extension for Synology NAS.",
65+
66+
"about_me": "About me. My projects, experiences and skills.",
67+
68+
"synology_download": "A chrome extension for Synology Download. Manage your downloads and files.",
69+
"trakt_extension": "A chrome extension for Trakt.tv. Keep track of your favorite TV shows and movies.",
70+
"reddit_extension": "A chrome extension for Reddit. Catch up on your favorite subreddits.",
71+
"neo_svelte": "A neomorphic UI library for Svelte 5.",
72+
"svelte_simple_router": "A simple SPA router for Svelte 5.",
73+
"image_viewer": "A simple image viewer."
5374
}
5475
}

src/i18n/models/routes.fr.json

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,21 @@
2727

2828
"title": {
2929
"home": "Dinh-Van Colomban | Project portfolio",
30+
3031
"trakt": "Trakt | Une extension chrome pour Trakt.tv",
3132
"trakt_demo": "Trakt Demo | Une démo interactive pour Side Trakt",
33+
3234
"synology": "Synology | Une extension chrome pour les NAS Synology",
3335
"synology_demo": "Synology Demo | Une démo interactive pou Synology Download",
34-
"syno_trakt_app": "Syno-Trakt | Une application react native pour Synology Download et Trakt.tv",
35-
"syno_trakt_app_demo": "Syno-Trakt Demo | Une démo interactive pour Syno-Trakt",
36+
3637
"about_me": "A propos | A propos de mes projects et expériences.",
3738
"contact": "Contact | Formulaire de contact",
39+
3840
"not_found": "404 | Page non trouvée",
3941
"unauthorized": "401 | Page non autorisée",
4042
"forbidden": "403 | Page interdite",
4143
"error": "500 | Erreur interne du serveur",
44+
4245
"particles": "Background | Particules animées",
4346
"beams": "Background | Faisceaux animés",
4447
"redirect_to": "Redirect | Redirection vers une autre page",
@@ -47,8 +50,26 @@
4750
"trakt_extension": "Trakt Extension | Une extension chrome pour Trakt.tv",
4851
"reddit_extension": "Reddit Extension | Une extension chrome pour Reddit",
4952
"neo_svelte": "Neo Svelte | Une library d'UI neomorphic for svelte 5",
50-
"svelte_simple_router": "Svelte Simple Router | Un routeur simple pour Svelte 5",
51-
"image_viewer": "Image Viewer | Un simple visualiseur d'images",
52-
"syno_trakt": "Syno-Trakt | Une application react native pour Synology Download et Trakt.tv"
53+
"svelte_simple_router": "Svelte Simple Router | Un simple router SPA pour Svelte 5",
54+
"image_viewer": "Image Viewer | Un simple visualiseur d'images"
55+
},
56+
57+
"description": {
58+
"home": "Site personnel de Dinh-Van Colomban. Mes projets, démos et portfolio.",
59+
60+
"trakt": "Une extension chrome pour Trakt.tv. Suivez vos séries et films préférés.",
61+
"trakt_demo": "Une démo interactive pour Side Trakt. Une extension chrome pour Trakt.tv.",
62+
63+
"synology": "Une extension chrome pour Synology NAS. Gérez vos téléchargements et fichiers.",
64+
"synology_demo": "Une démo interactive pour Synology Download. Une extension chrome pour Synology NAS.",
65+
66+
"about_me": "A propos de Dinh-Van Colomban. Mes projets et expériences.",
67+
68+
"synology_download": "Une extension chrome pour Synology NAS. Gérez vos téléchargements et fichiers.",
69+
"trakt_extension": "Une extension chrome pour Trakt.tv. Suivez vos séries et films préférés.",
70+
"reddit_extension": "Une extension chrome pour Reddit. Suivez vos subreddits préférés.",
71+
"neo_svelte": "Une library d'UI neomorphic pour Svelte 5.",
72+
"svelte_simple_router": "Un simple router SPA pour Svelte 5.",
73+
"image_viewer": "Un simple visualiseur d'images."
5374
}
5475
}

src/services/router/routes.service.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ export type RouteMeta = {
3232
path: Routes;
3333
name: keyof typeof Routes;
3434
title: string;
35+
description?: string;
36+
image?: string;
37+
url?: string;
3538
navbar?: boolean;
3639
more?: boolean;
3740
external?: boolean;
@@ -86,6 +89,7 @@ export const RoutesMeta: Record<keyof typeof Routes, RouteMeta> = {
8689
path: Routes.Home,
8790
name: 'Home',
8891
title: 'routes.title.home',
92+
description: 'routes.description.home',
8993
navbar: true,
9094
color: Colors.White,
9195
accentColor: Colors.White,
@@ -95,6 +99,7 @@ export const RoutesMeta: Record<keyof typeof Routes, RouteMeta> = {
9599
path: Routes.SynologyDemo,
96100
name: 'SynologyDemo',
97101
title: 'routes.title.synology_demo',
102+
description: 'routes.description.synology_demo',
98103
navbar: true,
99104
color: Colors.White,
100105
bgColor: Colors.Black,
@@ -105,6 +110,7 @@ export const RoutesMeta: Record<keyof typeof Routes, RouteMeta> = {
105110
path: Routes.TraktDemo,
106111
name: 'TraktDemo',
107112
title: 'routes.title.trakt_demo',
113+
description: 'routes.description.trakt_demo',
108114
navbar: true,
109115
accentColor: Colors.Trakt,
110116
color: Colors.White,
@@ -115,6 +121,7 @@ export const RoutesMeta: Record<keyof typeof Routes, RouteMeta> = {
115121
path: Routes.Synology,
116122
name: 'Synology',
117123
title: 'routes.title.synology',
124+
description: 'routes.description.synology',
118125
color: Colors.White,
119126
bgColor: Colors.Theme,
120127
navbar: true,
@@ -123,13 +130,15 @@ export const RoutesMeta: Record<keyof typeof Routes, RouteMeta> = {
123130
path: Routes.Trakt,
124131
name: 'Trakt',
125132
title: 'routes.title.trakt',
133+
description: 'routes.description.trakt',
126134
color: Colors.White,
127135
navbar: true,
128136
},
129137
AboutMe: {
130138
path: Routes.AboutMe,
131139
name: 'AboutMe',
132140
title: 'routes.title.about_me',
141+
description: 'routes.description.about_me',
133142
navbar: true,
134143
accentColor: Colors.White,
135144
bgColor: Colors.Theme,
@@ -270,7 +279,7 @@ export const RoutesDefinitions: RouteDefinition[] = [
270279
},
271280
];
272281

273-
export type ExternalRoute = Pick<RouteMeta, 'title' | 'external'> & { path: string; name: string };
282+
export type ExternalRoute = Pick<RouteMeta, 'title' | 'description' | 'url' | 'image' | 'external'> & { path: string; name: string };
274283

275284
export type BaseRoute = RouteMeta | ExternalRoute;
276285

@@ -279,42 +288,49 @@ export const externalRoutes: ExternalRoute[] = [
279288
path: `${AppLink.pages}/about-me`,
280289
name: 'AboutMe',
281290
title: 'routes.title.about_me',
291+
description: 'routes.description.about_me',
282292
external: true,
283293
},
284294
{
285295
path: `${AppLink.pages}/synology-download`,
286296
name: 'SynologyDownload',
287297
title: 'routes.title.synology_download',
298+
description: 'routes.description.synology_download',
288299
external: true,
289300
},
290301
{
291302
path: `${AppLink.pages}/trakt-extension`,
292303
name: 'TraktExtension',
293304
title: 'routes.title.trakt_extension',
305+
description: 'routes.description.trakt_extension',
294306
external: true,
295307
},
296308
{
297309
path: `${AppLink.pages}/reddit-extension`,
298310
name: 'RedditExtension',
299311
title: 'routes.title.reddit_extension',
312+
description: 'routes.description.reddit_extension',
300313
external: true,
301314
},
302315
{
303316
path: `${AppLink.pages}/svelte-simple-router`,
304317
name: 'SvelteSimpleRouter',
305318
title: 'routes.title.svelte_simple_router',
319+
description: 'routes.description.svelte_simple_router',
306320
external: true,
307321
},
308322
{
309323
path: `${AppLink.pages}/neo-svelte`,
310324
name: 'NeoSvelte',
311325
title: 'routes.title.neo_svelte',
326+
description: 'routes.description.neo_svelte',
312327
external: true,
313328
},
314329
{
315330
path: `${AppLink.pages}/image-viewer`,
316331
name: 'ImageViewer',
317332
title: 'routes.title.image_viewer',
333+
description: 'routes.description.image_viewer',
318334
external: true,
319335
},
320336
];

0 commit comments

Comments
 (0)