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-starlightfor 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-starlightand runnpm run devto start the dev server.CTRL+Cto 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.astroAdding 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.