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:
-
Install node.js
-
Go to the command prompt and create a folder, for example:
mkdir %USERPROFILE%\Documents\starlight
-
Go to the folder, for example:
cd %USERPROFILE%\Documents\starlight
-
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
- Where should we create your new project (type in):
-
I personally prefer to disable telemetry:
npm run astro telemetry disable
-
Next, I added the following integrations and plugins:
- MDX:
npx astro add mdx
- Starlight Blog:
npm i starlight-blog
- Starlight Utils:
npm i @lorenzo_lewis/starlight-utils
- 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
- MDX:
-
Enter your project directory using
cd fictionbecomesfact-starlight
and runnpm 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:
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 schemadocsSchema({ 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:
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:
---title: A new website - Jekyll to Astro Starlight migrationdescription: The website has been updated and I have chosen to replace Jekyll with Astro Starlightdate: 2025-02-10# lastUpdated: 2025-02-10tags: - Development - Workflowexcerpt: The website has been updated and I have chosen to replace Jekyll with Astro Starlight.featured: falsedraft: falseslug: notes/jekyll-astro-starlight-migration# cover:# alt: A beautiful cover image# image: ../../../assets/cover.webpgraph: visible: truebacklinks: visible: truecomments_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} />
No comments found for this note.
Join the discussion for this note on Github. Comments appear on this page instantly.