--- title: Migrating TDS from Docsify to Hugo date: '2026-02-07T12:01:10+08:00' categories: - llms - coding - education description: AI-assisted migration makes it feasible for non-experts to move course sites across stacks quickly, reducing dependence on LMSs and specialized coding knowledge. keywords: [Docsify, Hugo, migration, Codex, education technology, static sites] --- This morning, I migrated my [Tools in Data Science course page](https://tds.s-anand.net/) from [Docsify](https://docsify.js.org/) to [Hugo](https://gohugo.io/) using [Codex](https://openai.com/codex/). **Why?** Because Docsify was great for a single term. For multiple terms, archives became complex. I _still could_ have made it work, but it felt like time to move towards a static site generator. I don't know how [Hugo](https://gohugo.io/) or [Go](https://golang.org/) work. I didn't look at the code. I just gave Codex instructions and it did the rest. This gives me a bit more confidence that educators can start creating their own course sites without needing coding or platforms. Soon, they might not be stuck to [LMS](https://en.wikipedia.org/wiki/Learning_management_system)s either - they can build their own. Here are the prompts I used, along with Codex's responses, leading to two commits: - [Migrate from Docsify to Hugo deployment](https://github.com/sanand0/tools-in-data-science-public/commit/8587bdcf8afbbc5f6b2fbae94921e043bcc62ed8) - [feat(site): dynamic course detection and improved sidebar navigation](https://github.com/sanand0/tools-in-data-science-public/commit/168f69827c121307c9b1186afc7c2f0b9b71fa7f) --- ### Prompt 1 Generate a MIGRATION-PLAN.md for migrating this student course site from docsify to Hugo. Currenty, this site uses docsify to render Markdown as HTML on the fly. Create a setup.sh that generates a static version of the site under public/ using Hugo. Use a popular, elegant, minimal Hugo theme of your choice. We want to retain the sidebar navigation, as well as the archives under 2025-01/, 2025-05/, 2025-09/, and more in the future. Minimize the custom coding needed to achieve this.
Agent response I’ll inspect the repository structure to map the current Docsify content layout, then I’ll create `MIGRATION-PLAN.md` and a `setup.sh` that builds a Hugo static site into `public/` with minimal custom logic and preserved sidebar/archive organization. I found the Docsify setup and the key files (`index.html`, root `_sidebar.md`, plus archive subfolders with their own `_sidebar.md`/`README.md`). Next I’ll inspect those files and then draft a migration plan plus an idempotent `setup.sh` that maps this structure into Hugo with minimal custom templates. I have enough context to implement this cleanly. I’m now choosing a Hugo docs theme and validating its sidebar configuration model so `setup.sh` can auto-generate navigation from your existing `_sidebar.md` files with minimal maintenance for future archive terms. I validated `hugo-book` and will use it because it gives a built-in left docs sidebar with minimal configuration. I’ll now implement `setup.sh` to generate a Hugo workspace from your existing markdown tree and build to `public/`, then add `MIGRATION-PLAN.md` describing the migration steps and rationale. I’m about to add two files: `setup.sh` (idempotent Hugo build pipeline into `public/`) and `MIGRATION-PLAN.md` (phased migration plan, structure mapping, and rollout checks). I’ll keep the approach low-code by relying on Hugo Book’s built-in sidebar behavior and automatic archive folder discovery. I’ve written both files and will quickly sanity-check them (including a dry run of `setup.sh` in this environment, which should currently fail early because `hugo` isn’t installed here). I found one cleanup point: `setup.sh` checked for `rsync` even though it doesn’t use it. I’ll remove that extra dependency and then provide a concise summary of what was added. Created both requested files: 1. `MIGRATION-PLAN.md` 2. `setup.sh` What I implemented: - Chose `hugo-book` as the theme (popular, minimal, docs-style sidebar). - `setup.sh` now: - Creates an isolated Hugo workspace at `.hugo-build/site` - Clones `hugo-book` - Generates `hugo.toml` - Copies tracked markdown into Hugo `content/` - Converts every `README.md` to `_index.md` (so `/`, `/2025-01/`, `/2025-05/`, `/2025-09/` keep clean section URLs) - Skips Docsify-only `_sidebar.md` - Copies all tracked non-markdown files into Hugo `static/` - Builds static output into `public/` Notes: - I could not run a full build here because `hugo` is not installed in this environment (`Error: missing required command 'hugo'`). - Once Hugo Extended is installed, run: ```bash ./setup.sh ``` Files: - `setup.sh` - `MIGRATION-PLAN.md`
--- ### Prompt 2 Use `mise x hugo -- hugo` and run and test it.
Agent response I’ll run `setup.sh` through `mise x hugo --` so Hugo is available in PATH for the script, then verify the generated `public/` output and key archive routes. The first run failed because `mise` couldn’t write under `~/.cache/mise` in this sandbox. I’ll rerun using a temporary cache directory and then validate the generated site. `mise x hugo -- hugo` is installing the standard Hugo binary (not Extended), so the script’s Extended check fails. I’ll quickly check the available `mise` variants and use an Extended one to complete the test run. `mise` does not expose an “extended” Hugo variant here. I’ll make `setup.sh` tolerant of standard Hugo (warn instead of hard-fail), then run it with `mise x hugo --` and verify whether the build succeeds end-to-end. The build failed exactly at SCSS compilation, so we do need Hugo Extended for `hugo-book`. I’m testing `mise x hugo@extended -- hugo` with temporary mise data/cache dirs to keep everything inside writable paths. Found the issue: with `mise`, Extended is a separate tool named `hugo-extended` (not a variant of `hugo`). I’ll run using that to complete the test build. Build now succeeds with Hugo Extended. I’m validating the generated `public/` output, including root and archive routes plus sidebar links. Ran and tested. Results: 1. `mise x hugo -- hugo version` - Output: `hugo v0.153.3 ...` (non-extended) 2. `mise x hugo -- ./setup.sh` - Fails at SCSS compile (`TOCSS ... you need the extended version`) because `hugo-book` requires Hugo Extended. 3. `mise x hugo-extended -- hugo version` - Output: `hugo v0.155.2+extended ...` 4. `mise x hugo-extended -- ./setup.sh` - Succeeds. - Generated site at `public/` - Build summary: `Pages 289`, `Static files 103`, total ~1.6s. Validation checks passed: - `public/index.html` exists - `public/2025-01/index.html` exists - `public/2025-05/index.html` exists - `public/2025-09/index.html` exists - Sidebar contains links for archive terms and pages like `marks-dashboard` and `system-requirements`. I also adjusted `setup.sh` so non-extended Hugo emits a warning instead of exiting immediately (`setup.sh`). The actual build still correctly fails later if the active theme needs Extended.
--- ### Prompt 3 The sidebar for the home page should only contain the contains of \_sidebar.md. The sidebar for 2025-01/, 2025-05/, and 2025-09/ should only contain the contents of the respective folders' \_sidebar.md. Convert any links to images/ to an absolute link starting with /images/. Re-run.
Agent response I’ll update `setup.sh` to generate section-specific sidebars directly from each `_sidebar.md` (root and archive folders), override Hugo Book’s menu partial to use those sidebars, rewrite `images/` links to `/images/`, then rebuild and verify the output. I’m editing `setup.sh` now to: 1) normalize `_sidebar.md` into per-section sidebar files, 2) override Hugo Book’s menu partial to render only the correct sidebar by section, and 3) rewrite markdown links from `images/` or `../images/` to `/images/`. Then I’ll rebuild and verify. Implemented and re-ran with your requirements. Changes made in `setup.sh`: - Sidebar behavior: - Added per-section sidebar generation from source `_sidebar.md` files: - root: `_sidebar.md` - `2025-01/`: `2025-01/_sidebar.md` - `2025-05/`: `2025-05/_sidebar.md` - `2025-09/`: `2025-09/_sidebar.md` - Added a Hugo Book partial override at `.hugo-build/site/layouts/_partials/docs/menu-filetree.html` during build so: - home and non-archive pages use only root `_sidebar.md` - pages under `/2025-01/`, `/2025-05/`, `/2025-09/` use only their own folder sidebar - Link normalization in sidebars: - Converts `.md` links to Hugo-style paths (e.g. `/foo/`) - Normalizes sidebar-local links like `http-requests` to `/http-requests/` - Removes docsify inline `