This is an extension to 📝 Generating Slug From Title In Astro

The changes are similar to the previous article but will require an additional library to format the timestamp from frontmatter.

slugDate function #

First install moment

pnpm add moment

Next create a new function in src/lib/slugDate.ts

import { default as moment } from 'moment'
export default function (date: string) {
  const m = moment(date)
  date = `${m.format('YYYY')}/${m.format('MM')}/${m.format('DD')}/`
  return date
}

Slug Generation #

Call slugDate referencing post.data.date aswell as createSlug referencing post.data.title.

toISOString is required to change date to a string for types.

// src/pages/blog/[...slug].astro
export async function getStaticPaths() {
  const posts = await getCollection("blog");
  return posts.map((post) => ({
-    params: { slug: createSlug(post.data.title) },
+    params: {
+      slug:
+        slugDate(post.data.date.toISOString()) +
+        createSlug(post.data.title),
+    },
    props: post,
  }));
}
type Props = CollectionEntry<"blog">;

Blog Post Links #

Similar to above call slugDate referencing post.data.date aswell as createSlug referencing post.data.title

// src/pages/blog/index.astro
-  <a href={`/blog/${createSlug(post.data.title)}/`}>
+  <a href={`/blog/${slugDate(post.data.date.toISOString())}
+  ${createSlug(post.data.title)}/`}>
    {post.data.title}
  </a>

Bonus #

Now all blog posts are using YYYY/MM/DD/title there is no need for /blog/ so it is now possible to move src/pages/blog/[...slug].astro to src/pages/[...slug].astro as all blog posts will have unique slugs.

This cleans up urls a bit & is the same setup I have on my gatsby site.

Source #

The source for my astro blog is available on github.

blog-astro