diff --git a/cspell.config.yaml b/cspell.config.yaml
index 8de14534..28398ec7 100644
--- a/cspell.config.yaml
+++ b/cspell.config.yaml
@@ -33,3 +33,4 @@ ignorePaths:
ignoreRegExpList:
- # ignore HTML comments
- '@[A-Za-z0-9-_]+' # ignore social handles
+ - '"[a-z0-9-]+"' # ignore SLUGS
diff --git a/cspell/terminology.txt b/cspell/terminology.txt
index d4103558..a6f3fa14 100644
--- a/cspell/terminology.txt
+++ b/cspell/terminology.txt
@@ -33,6 +33,7 @@ orcid
pagefind
prophoto-rgb
respec
+roundtable
secno
shiki
sotd
@@ -43,4 +44,4 @@ tocsidebar
unbuilt
wireframing
workstreams
-wght
\ No newline at end of file
+wght
diff --git a/www/src/content.config.ts b/www/src/content.config.ts
new file mode 100644
index 00000000..f4c674ef
--- /dev/null
+++ b/www/src/content.config.ts
@@ -0,0 +1,35 @@
+import { z, defineCollection } from 'astro:content';
+import { file, glob } from 'astro/loaders';
+
+const DATE = z
+ .string()
+ .or(z.date())
+ .transform((val) => new Date(val));
+
+const w3c = defineCollection({
+ loader: file('src/content/w3c.json'),
+ schema: () =>
+ z.object({
+ title: z.string(),
+ date: DATE,
+ author: z.string(),
+ url: z.string(),
+ }),
+});
+
+const posts = defineCollection({
+ loader: glob({ pattern: ['*.md'], base: 'src/content/posts' }),
+ schema: () =>
+ z.object({
+ title: z.string(),
+ date: DATE,
+ description: z.optional(z.string()),
+ author: z.string(),
+ tags: z.optional(z.array(z.string())),
+ }),
+});
+
+export const collections = {
+ posts,
+ w3c,
+};
diff --git a/www/src/content/config.ts b/www/src/content/config.ts
deleted file mode 100644
index 3bb1469b..00000000
--- a/www/src/content/config.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-// Import utilities from `astro:content`
-import { z, defineCollection } from 'astro:content';
-// Define a `type` and `schema` for each collection
-const postsCollection = defineCollection({
- type: 'content',
- schema: ({ image }) =>
- z
- .object({
- title: z.string(),
- date: z
- .string()
- .or(z.date())
- .transform((val) => new Date(val)),
- // description: z.string(),
- author: z.string(),
- // tags: z.array(z.string()),
- })
- .strict(),
-});
-// Export a single `collections` object to register your collection(s)
-export const collections = {
- posts: postsCollection,
-};
diff --git a/www/src/content/posts.ts b/www/src/content/posts.ts
deleted file mode 100644
index 15976575..00000000
--- a/www/src/content/posts.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-// cSpell:words roundtable
-
-type Post = {
- title: string;
- date: string;
- author: string;
- url?: string;
-};
-
-export const posts: Post[] = [
- {
- title: "Call to read the First Public Editor's Draft and share feedback",
- date: '2021-09-23',
- author: 'Kaelig Deloumeau-Prigent',
- url: 'https://www.w3.org/community/design-tokens/2021/09/23/call-to-read-the-first-public-editors-draft-and-share-feedback/',
- },
- {
- title: 'Upcoming event: design tool vendor roundtable',
- date: '2021-03-09',
- author: 'Kaelig Deloumeau-Prigent',
- url: 'https://www.w3.org/community/design-tokens/2021/03/09/upcoming-event-design-tool-vendor-roundtable/',
- },
- {
- title: 'Status update (February 2021)',
- date: '2021-02-15',
- author: 'James Nash',
- url: 'https://www.w3.org/community/design-tokens/2021/02/15/status-update-february-2021/',
- },
- {
- title: "First Editor's Draft shared with design tooling vendors",
- date: '2021-04-17',
- author: 'Kaelig Deloumeau-Prigent',
- url: 'https://www.w3.org/community/design-tokens/2021/04/17/first-editors-draft-shared-with/',
- },
- {
- title: "Call to implement the Second Editors' Draft and share feedback",
- date: '2022-06-14',
- author: 'Kaelig Deloumeau-Prigent',
- url: 'https://www.w3.org/community/design-tokens/2022/06/14/call-to-implement-the-second-editors-draft-and-share-feedback/',
- },
- {
- title:
- 'Request For Comments: new Resolver specification, groups & Aliases updates',
- date: '2025-09-12',
- author: 'Kaelig Deloumeau-Prigent',
- url: 'https://www.w3.org/community/design-tokens/2025/09/12/request-for-comments-new-resolver-specification-groups-aliases-updates/',
- },
- {
- title: 'Design Tokens specification reaches first stable version',
- date: '2025-10-28',
- author: 'Kaelig Deloumeau-Prigent',
- url: 'https://www.w3.org/community/design-tokens/2025/10/28/design-tokens-specification-reaches-first-stable-version/',
- },
-];
diff --git a/www/src/content/w3c.json b/www/src/content/w3c.json
new file mode 100644
index 00000000..15e75b7c
--- /dev/null
+++ b/www/src/content/w3c.json
@@ -0,0 +1,51 @@
+[
+ {
+ "id": "call-to-read-the-first-public-editors-draft-and-share-feedback",
+ "title": "Call to read the First Public Editor's Draft and share feedback",
+ "date": "2021-09-23",
+ "author": "Kaelig Deloumeau-Prigent",
+ "url": "https://www.w3.org/community/design-tokens/2021/09/23/call-to-read-the-first-public-editors-draft-and-share-feedback/"
+ },
+ {
+ "id": "upcoming-event-tool-vendor-roundtable",
+ "title": "Upcoming event: design tool vendor roundtable",
+ "date": "2021-03-09",
+ "author": "Kaelig Deloumeau-Prigent",
+ "url": "https://www.w3.org/community/design-tokens/2021/03/09/upcoming-event-design-tool-vendor-roundtable/"
+ },
+ {
+ "id": "status-update-february-2021",
+ "title": "Status update (February 2021)",
+ "date": "2021-02-15",
+ "author": "James Nash",
+ "url": "https://www.w3.org/community/design-tokens/2021/02/15/status-update-february-2021/"
+ },
+ {
+ "id": "first-editors-draft-shared-with-design-tooling-vendors",
+ "title": "First Editor's Draft shared with design tooling vendors",
+ "date": "2021-04-17",
+ "author": "Kaelig Deloumeau-Prigent",
+ "url": "https://www.w3.org/community/design-tokens/2021/04/17/first-editors-draft-shared-with/"
+ },
+ {
+ "id": "call-to-implement-the-second-editors-draft-and-share-feedback",
+ "title": "Call to implement the Second Editors' Draft and share feedback",
+ "date": "2022-06-14",
+ "author": "Kaelig Deloumeau-Prigent",
+ "url": "https://www.w3.org/community/design-tokens/2022/06/14/call-to-implement-the-second-editors-draft-and-share-feedback/"
+ },
+ {
+ "id": "request-for-comments-new-resolver-specification-groups-aliases-updates",
+ "title": "Request For Comments: new Resolver specification, groups & Aliases updates",
+ "date": "2025-09-12",
+ "author": "Kaelig Deloumeau-Prigent",
+ "url": "https://www.w3.org/community/design-tokens/2025/09/12/request-for-comments-new-resolver-specification-groups-aliases-updates/"
+ },
+ {
+ "id": "design-tokens-specification-reaches-first-stable-version",
+ "title": "Design Tokens specification reaches first stable version",
+ "date": "2025-10-28",
+ "author": "Kaelig Deloumeau-Prigent",
+ "url": "https://www.w3.org/community/design-tokens/2025/10/28/design-tokens-specification-reaches-first-stable-version/"
+ }
+]
diff --git a/www/src/pages/blog.astro b/www/src/pages/blog.astro
deleted file mode 100644
index c69b7c6a..00000000
--- a/www/src/pages/blog.astro
+++ /dev/null
@@ -1,62 +0,0 @@
----
-import { getW3FormattedDate, getFormattedDate } from '@/utils/date.utils';
-import { posts } from '@/content/posts';
-import Base from '@/layouts/Base.astro';
-import Text from '@/components/Text/Text.astro';
-import Stack from '@/components/Stack/Stack.astro';
-import { Icon } from 'astro-icon/components';
-
-const title = 'Blog';
-
-const sortedPosts = posts.sort(
- (a, b) => new Date(b.date).valueOf() - new Date(a.date).valueOf(),
-);
-
-const formattedPosts = sortedPosts.map((post) => {
- const formattedPost = {
- title: post.title,
- author: post.author,
- w3FormattedDate: getW3FormattedDate(post.date),
- formattedDate: getFormattedDate(post.date),
- url: post.url?.startsWith('http') ? post.url : `/posts/${post.url}/`,
- };
- return formattedPost;
-});
----
-
-
-
- {
- formattedPosts.map((post) => (
-
-
-
- {post.title}
-
-
-
-
-
-
-
- ))
- }
-
-
-
-
diff --git a/www/src/pages/blog/[id].astro b/www/src/pages/blog/[id].astro
new file mode 100644
index 00000000..e7ba29c9
--- /dev/null
+++ b/www/src/pages/blog/[id].astro
@@ -0,0 +1,19 @@
+---
+import Base from '@/layouts/Base.astro';
+import { getCollection, render } from 'astro:content';
+
+export async function getStaticPaths() {
+ const posts = await getCollection('posts');
+ return posts.map((post) => ({
+ params: { id: post.id },
+ props: { post },
+ }));
+}
+
+const { post } = Astro.props;
+const { Content } = await render(post);
+---
+
+
+
+
diff --git a/www/src/pages/blog/index.astro b/www/src/pages/blog/index.astro
new file mode 100644
index 00000000..5e6281bc
--- /dev/null
+++ b/www/src/pages/blog/index.astro
@@ -0,0 +1,60 @@
+---
+import { getCollection } from 'astro:content';
+import { getW3FormattedDate, getFormattedDate } from '@/utils/date.utils';
+import Base from '@/layouts/Base.astro';
+import Text from '@/components/Text/Text.astro';
+import Stack from '@/components/Stack/Stack.astro';
+import { Icon } from 'astro-icon/components';
+
+const title = 'Blog';
+
+const posts = await getCollection('posts');
+const w3c = await getCollection('w3c');
+
+const sortedPosts = [...posts, ...w3c].sort(
+ (a, b) => b.data.date.getTime() - a.data.date.getTime(),
+);
+---
+
+
+
+ {
+ sortedPosts.map((post) => (
+
+
+ {post.collection === 'w3c' ? (
+
+ {post.data.title}
+
+
+ ) : (
+ {post.data.title}
+ )}
+
+
+
+
+
+ ))
+ }
+
+
+
+