diff --git a/src/layouts/BlogSubpage.astro b/src/layouts/BlogSubpage.astro
new file mode 100644
index 0000000..57f341d
--- /dev/null
+++ b/src/layouts/BlogSubpage.astro
@@ -0,0 +1,39 @@
+---
+import BaseLayout from '../layouts/BaseLayout.astro';
+import NavLink from '../components/NavLink.astro';
+
+export interface Props {
+ title: string;
+ description: string;
+}
+
+const { title, description } = Astro.props;
+---
+
+
+
+ My blog
+
+
+
+
+
+
diff --git a/src/pages/blog/categories/[category].astro b/src/pages/blog/categories/[category].astro
new file mode 100644
index 0000000..71ef5e4
--- /dev/null
+++ b/src/pages/blog/categories/[category].astro
@@ -0,0 +1,25 @@
+---
+import type { CollectionEntry } from 'astro:content';
+
+import BlogSubpage from '../../../layouts/BlogSubpage.astro';
+import PostList from '../../../components/PostList.astro';
+import frontMatterConfig from '../../../../frontmatter.json';
+
+export function getStaticPaths() {
+ const categories = frontMatterConfig['frontMatter.taxonomy.categories'];
+ return categories.map((category) => ({ params: { category } }));
+}
+
+const { category } = Astro.params;
+
+const filterFn = (entry: CollectionEntry<'blog'>) =>
+ entry.data.categories.includes(category as string);
+---
+
+
+ {category} posts
+
+
diff --git a/src/pages/blog/categories/index.astro b/src/pages/blog/categories/index.astro
new file mode 100644
index 0000000..cc31408
--- /dev/null
+++ b/src/pages/blog/categories/index.astro
@@ -0,0 +1,20 @@
+---
+import BlogSubpage from '../../../layouts/BlogSubpage.astro';
+import frontMatterConfig from '../../../../frontmatter.json';
+
+const categories = frontMatterConfig['frontMatter.taxonomy.categories'];
+---
+
+
+
+ {
+ categories.sort().map((category) => (
+ -
+
+ {category}
+
+
+ ))
+ }
+
+
diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro
index 0ad61e6..bea0945 100644
--- a/src/pages/blog/index.astro
+++ b/src/pages/blog/index.astro
@@ -1,31 +1,11 @@
---
-import BaseLayout from '../../layouts/BaseLayout.astro';
+import BlogSubpage from '../../layouts/BlogSubpage.astro';
import PostList from '../../components/PostList.astro';
-import NavLink from '../../components/NavLink.astro';
---
-
-
- My blog
-
-
-
-
-
-
+
+
diff --git a/src/pages/blog/tags/[tag].astro b/src/pages/blog/tags/[tag].astro
new file mode 100644
index 0000000..410bbfb
--- /dev/null
+++ b/src/pages/blog/tags/[tag].astro
@@ -0,0 +1,25 @@
+---
+import type { CollectionEntry } from 'astro:content';
+
+import BlogSubpage from '../../../layouts/BlogSubpage.astro';
+import PostList from '../../../components/PostList.astro';
+import frontMatterConfig from '../../../../frontmatter.json';
+
+export function getStaticPaths() {
+ const tags = frontMatterConfig['frontMatter.taxonomy.tags'];
+ return tags.map((tag) => ({ params: { tag } }));
+}
+
+const { tag } = Astro.params;
+
+const filterFn = (entry: CollectionEntry<'blog'>) =>
+ entry.data.tags.includes(tag as string);
+---
+
+
+ Posts tagged {tag}
+
+
diff --git a/src/pages/blog/tags/index.astro b/src/pages/blog/tags/index.astro
new file mode 100644
index 0000000..cb0c1d2
--- /dev/null
+++ b/src/pages/blog/tags/index.astro
@@ -0,0 +1,31 @@
+---
+import BlogSubpage from '../../../layouts/BlogSubpage.astro';
+import frontMatterConfig from '../../../../frontmatter.json';
+
+const tags = frontMatterConfig['frontMatter.taxonomy.tags'];
+---
+
+
+
+
+
+