Skip to content

A new website - Jekyll to Astro Starlight migration

Introduction

In 2021, I made the choice to use a Jekyll template as an alternative to Obsidian Publish. And now, a few years later, it was time to take the next step. There were some bugs in the Jekyll website and I wanted, among other things:

  • a dark theme
  • a search function
  • more functionality, such as Tabs, Steps and Code components
  • to retain markdown notes (posts)
  • to keep the workflow with the Github repository and build functionality via Cloudflare
  • to retain the graph view and backlinks components
  • to keep the comments functionality via Github

After a long search, I finally made the decision to migrate from Jekyll to Astro Starlight with plugins like blog, site-graph, and starlight-utils. My workflow would change: I would no longer create notes (posts) using Obsidian but with VS Code using the MDX syntax and plugin. Below, I describe the steps I followed.

How To

Installation and creating the project

Below are the steps I followed on a Windows machine:

  1. Install node.js

  2. Go to the command prompt and create a folder, for example: mkdir %USERPROFILE%\Documents\starlight

  3. Go to the folder, for example: cd %USERPROFILE%\Documents\starlight

  4. Create a new project: npm create astro@latest -- --template starlight

    • Where should we create your new project (type in): ./fictionbecomesfact-starlight for example
    • Do you plan to write TypeScript: yes
    • How strict should typescript be: Strict (recommended)
    • Install dependencies: Yes
    • Initialize a new git repository: Yes

    The project has now been created. Read more about the project structure here

  5. I personally prefer to disable telemetry: npm run astro telemetry disable

  6. Next, I added the following integrations and plugins:

    • Starlight Site Graph: npm i starlight-site-graph
    • Other plugins: npm i sass-embedded rehype-slug rehype-autolink-headings @astrojs/markdown-remark remark-custom-heading-id
  7. Enter your project directory using cd fictionbecomesfact-starlight and run npm run dev to start the dev server. CTRL+C to stop. Now you can visit your site by browsing to: http://localhost:4321/

Configuration

I modified the config.ts file as follows:

src/content/config.ts
import { defineCollection, z } from 'astro:content';
import { docsSchema } from '@astrojs/starlight/schema';
import { pageSiteGraphSchema } from 'starlight-site-graph/schema';
import { blogSchema } from 'starlight-blog/schema';
export const collections = {
docs: defineCollection({
schema: docsSchema({
extend: (context) => blogSchema(context),
})
}),
};
// Extend the built-in schema
docsSchema({
extend: pageSiteGraphSchema
})
docsSchema({
extend: z.object({
// Add a new optional field to the schema.
comments_id: z.number().optional(),
}),
})

The necessary adjustments are made so that all plugins work and I added the comments_id field so that I can specify it in the frontmatter of a post which comments (GitHub issue) belong to the post.

Ultimately, my astro.config.mjs file looks like this:

./astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import starlightSiteGraph from 'starlight-site-graph';
import starlightBlog from 'starlight-blog';
import starlightUtils from "@lorenzo_lewis/starlight-utils";
import mdx from "@astrojs/mdx";
import { rehypeHeadingIds } from '@astrojs/markdown-remark';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import rehypeSlug from 'rehype-slug';
import { remarkHeadingId } from "remark-custom-heading-id";
export default defineConfig({
site: 'https://www.fictionbecomesfact.com',
redirects: {
'/digitalgarden': '/notes/digitalgarden',
// And many more redirects to migrate from the old site
},
build: {
inlineStylesheets: 'always'
},
markdown: {
remarkPlugins: [remarkHeadingId],
rehypePlugins: [
rehypeSlug,
rehypeHeadingIds,
[
rehypeAutolinkHeadings,
{
behavior: 'wrap', // Wrap the heading text in a link.
},
],
],
},
integrations: [starlight({
title: "Fiction Becomes Fact",
logo: {
light: '/src/assets/fbf-banner-light.webp',
dark: '/src/assets/fbf-banner-dark.webp',
replacesTitle: true,
},
favicon: '/images/favicon.png',
head: [
// Add ICO favicon fallback for Safari.
{
tag: 'link',
attrs: {
rel: 'icon',
href: '/images/favicon.ico',
sizes: '32x32',
},
},
{
tag: 'script',
attrs: {
src: '/scripts/showdown.min.js',
defer: true,
},
},
],
credits: false,
lastUpdated: false,
social: {
github: 'https://github.com/fictionbecomesfact',
},
customCss: [
'./src/styles/global.css' ,
'./src/styles/fontawesome.all.min.css', //The webfonts are added to /src/webfonts
'./src/styles/comments.scss',
'./src/styles/headings.css'
],
sidebar: [
{
label: "leadingNavLinks",
items: [
{ label: "Tech Notes", link: "/notes" },
],
},
],
components: {
Footer: './src/overrides/Footer.astro', //Override the footer
//The custom component Comments.astro is added to /src/components
},
plugins: [
starlightBlog({
title: '',
prefix: 'notes',
}),
starlightUtils({
navLinks: {
leading: { useSidebarLabelled: "leadingNavLinks" },
},
}),
starlightSiteGraph(),
],
}), mdx()],
devToolbar: { enabled: false },
});

The above configuration gives an idea of what you can configure. In this way, for example, I use custom CSS and have customized the footer through an override. It is also easy to add a script like Showdown to the head. Furthermore, I have changed the default prefix blog of the Starlight Blog plugin to notes.

Because I use the sidebar from the Starlight Blog plugin, it was also necessary to adjust references to the sidebar within the project, for example, those from the Starlight Utils plugin:

// Replace `import Default from "@astrojs/starlight/components/Sidebar.astro";` with:
import Default from "starlight-blog/overrides/Sidebar.astro";
// for the following files:
// node_modules\@lorenzo_lewis\starlight-utils\components\Sidebar.astro
// node_modules\@lorenzo_lewis\starlight-utils\components\HorizontalList.astro
// node_modules\@lorenzo_lewis\starlight-utils\components\Dropdown.astro

Adding content

Now you can create posts in the /src/content/docs/blog (or src/content/docs/notes in my case) by adding .md or .mdx files. Here is a MDX example with a full frontmatter, some text and the custom comments component:

src\content\docs\notes\jekyll-astro-starlight-migration.mdx
---
title: A new website - Jekyll to Astro Starlight migration
description: The website has been updated and I have chosen to replace Jekyll with Astro Starlight
date: 2025-02-10
# lastUpdated: 2025-02-10
tags:
- Development
- Workflow
excerpt: The website has been updated and I have chosen to replace Jekyll with Astro Starlight.
featured: false
draft: false
slug: notes/jekyll-astro-starlight-migration
# cover:
# alt: A beautiful cover image
# image: ../../../assets/cover.webp
graph:
visible: true
backlinks:
visible: true
comments_id: 77
# caution: comments_id is a custom field!
---
import Comments from '../../../components/Comments.astro';
import { Icon, LinkCard, CardGrid, Code, Tabs, TabItem, Badge, Steps } from '@astrojs/starlight/components';
## Hello
Hello world!
## <span style="display: flex; gap: 8px"><Icon name="external" /> Favorites</span>{#favorites}
<CardGrid>
<LinkCard title="Astro Starlight Docs" href="https://starlight.astro.build/getting-started" target="_blank"/>
</CardGrid>
## <span style="display: flex; gap: 8px"><i id='mdx-icon' class='fa fa-comments' style="text-decoration: none"></i> Comments</span>{#comments}
<Comments is:raw comments_id={frontmatter.comments_id} />

Favorites

Comments

    No comments found for this note.

    Join the discussion for this note on Github. Comments appear on this page instantly.

    Copyright 2021- Fiction Becomes Fact