Skip to content

Convert to MySTMD - #315

Open
lundybernard wants to merge 15 commits into
scientific-python:mainfrom
lundybernard:lb/myst-migration
Open

lundybernard wants to merge 15 commits into
scientific-python:mainfrom
lundybernard:lb/myst-migration

Conversation

@lundybernard

@lundybernard lundybernard commented May 13, 2026

Copy link
Copy Markdown

Migrate from Hugo to MyST-MD

Fixes: #279

@netlify

netlify Bot commented May 13, 2026

Copy link
Copy Markdown

Deploy Preview for learn-scientific-python-org ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 7703c47
🔍 Latest deploy log https://app.netlify.com/projects/learn-scientific-python-org/deploys/6aaaee0cb166e50008299560
😎 Deploy Preview https://deploy-preview-315--learn-scientific-python-org.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 85
Accessibility: 64
Best Practices: 100
SEO: 92
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@lundybernard

Copy link
Copy Markdown
Author

I've put together a plan for the migration, including REQUIREMENTS.md, and Architectural Decision Records (ADRs), which need review, and a detailed PLAN.md document.

Recommended Review order:

  • Start with REQUIREMENTS.md; a high-level list of goals, and details about how the change will be managed. Any changes to this doc will be top priority.
  • Review the ADRs in docs/decisions/0001-myst-migration/; they cover specific decisions that need to be made, and are the most important items to discuss.
  • The README files just provide context and an index of the directories, and should be helpful.
  • the PLAN.md doc contains a granular specifics, is likely to change as I work through the migration. It is helpful for the process, may be a valuable record of the completed work, but is probably not worth reviewing at this time.

Ai Tools Disclaimer:
These docs were generated using Claude Opus-4.7 for planning and review, Sonet-4.6 for edits, and GPT-5.5 for reviews.
I have read, reviewed, and updated the docs myself many times, and feel that they are ready for other humans to review and discuss.
Since scientific-python.org does not have an official Ai use policy, I'm using the SciPy project's policy as a guideline.

@lundybernard
lundybernard force-pushed the lb/myst-migration branch 2 times, most recently from 0f29f3f to 4f6f3c4 Compare May 13, 2026 18:11
@henryiii

Copy link
Copy Markdown
Contributor

From what I see, the plan looks fine. While I was excited about the Jekyll -> Hugo migration (fast, secure single binary, static easily themeable HTML), I'm not quite as excited about mystmd transition (Frankenstein of nodejs+Python, JS-powered pages). I get several source map loading errors when opening https://mystmd.org/guide. But I do really like it for course material, and some of our material basically is that.

I'd probably not worry about trying to replicate the theme at all at first (which I think matches the decisions made, like the deferred footer).

I'm curious if you've done the basic conversation table for the other subrepos? I'm curious to see what it says about the special stuff in cookie, like our tabs. I know exactly how to do that in Hugo (I maintain a Hugo theme ;) ), I'm curious to know how those would map to mystmd.

I'm very slightly tempted to do Jekyll -> Hugo with cookie, and then look at Hugo -> mystmd.

But yes, plan looks good. What do you feed into the next step, just the PLAN.md?

@lundybernard

Copy link
Copy Markdown
Author

I've only done a cursory look at converting the other sub-repos, a quick "is it possible, any major blockers?" check. Now's probably a good time to build a report and add it to the parent ticket.

I take a very hand-on approach with Ai tools, so I wont feed a big "one-shot" prompt into an agent and lets it run for hours. I've been using claude code, with broad read-only permissions, and it pulls in a lot of context about the repo when I start it up. So, the input is a heuristic search of the learn repository, and access to external docs as-needed.

@stefanv

stefanv commented May 18, 2026

Copy link
Copy Markdown
Member

For generic landing pages, we've started working on https://github.com/scientific-python/scientific-python-myst-theme/ (early stages of a cookie cutter).

Agreed that porting content first is a good idea: we can tweak the theme later.

myst is not supposed to be a "Frankenstein of nodejs+Python, JS-powered pages" — it is a typescript application (runtime Node or Bun). But, I get the concern about the complexity, and of course the source map errors should be addressed.

Hugo's big strength is in how easily extendible it is, without needing to tinker with the code, whereas myst themes are all full-fledged web servers & logic.

@lundybernard

Copy link
Copy Markdown
Author

Surfaced a bug:

> make html
git submodule update --init
myst build --html
...
⛔️ content/contributors/getting-started.md:23 Link has no URL: astropy
⛔️ content/contributors/getting-started.md:23 Link has no URL: sunpy
⛔️ content/contributors/getting-started.md:24 Link has no URL: numpy
⛔️ content/contributors/getting-started.md:24 Link has no URL: scipy
⛔️ content/contributors/getting-started.md:24 Link has no URL: matplotlib
⛔️ content/contributors/getting-started.md:40 Link has no URL: integrated development environment
...

Confirmed on the live site, these are dead-links on https://learn.scientific-python.org/contributors/getting-started/

@lundybernard
lundybernard force-pushed the lb/myst-migration branch 6 times, most recently from fd8312a to 58ef866 Compare May 20, 2026 19:32
@lundybernard
lundybernard marked this pull request as ready for review May 20, 2026 19:32
@lundybernard

lundybernard commented May 21, 2026

Copy link
Copy Markdown
Author

Known Regressions/Changes

Diff between the live site and the myst preview that I've found so far


🤖 AI text below 🤖

R1: Footer removed

Production footer contains:

  • Site links: About, Roadmap, Code of Conduct, SPECs, Summits, Calendars, Press kit
  • Social links: GitHub, YouTube, Mastodon, Discussion Forum, Discord
  • Copyright notice

Preview footer: only "Made with MyST" attribution.

The Hugo theme provided this footer.
no MyST equivalent is configured in myst.yml yet.
Already tracked in the migration plan as a deferred footer/quicklinks item.
a follow-up issue must be filed before merge per Phase 4 of the plan.


R2: On-page TOC relabeled (minor)

Production: right-side panel is labeled "On this page."

Preview: same panel, same links, labeled "CONTENTS."

MyST default label. No content difference.


R3: Breadcrumb nav replaced by full left sidebar (structural change)

Production: a minimal breadcrumb path below the top bar, e.g.
[home icon] > Contributor Guide > Why Contribute.

Preview: a full left-side column showing the entire site index, expanded to the
current section. The breadcrumb is gone.

This is MyST's default sidebar behavior.
The information is richer but the visual weight is much heavier than the Hugo breadcrumb. Decide whether to keep, configure to show only the current section, or file a follow-up to revisit post-merge.


R4: Page title format reversed (minor)

Site Format
Production Learn - Page Title
Preview Page Title - Learn Scientific Python

Consistent across all preview pages. Affects <title> tag and browser tab
only.


R5: Prev/next buttons show "Setup" instead of page title (new feature, label bug)

Prev/next navigation buttons are new; Hugo did not have them. They work
correctly (correct destination URLs) but all display "Setup" as the label
instead of the actual page title.

Root cause: the toc group in myst.yml is defined as:

- title: Setup
  children:
    - file: contributors/setup/install.md
    - file: contributors/setup/ecosystem.md
    - file: contributors/setup/next-steps.md

The title: Setup group node has no file:,
so MyST propagates the group label to its children's prev/next buttons.
Pages adjacent to a Setup child also inherit "Setup" as their neighbor label.

Fix options:

  1. Add contributors/setup/index.md and convert the group to a file: entry so each page has a real title.
  2. File an upstream MyST issue if this is a framework bug.

R6: Maintainers section now visible in sidebar (change)

On the Hugo site, /maintainers/ is not linked from any navigation element and
is only reachable by direct URL. It may have been orphaned deliberately while
the section was being drafted.

On the MyST preview, Maintainers appears as a top-level entry in the left
sidebar, making it discoverable to all visitors. Confirm whether this is
intentional before merging.


R7: Favicon missing in preview (fix pending)

The production Hugo site serves a favicon via the Hugo theme. The MyST preview
has no favicon. content/myst.yml references ../assets/images/favicon.ico
but the file has not been committed yet.

Fix options:

  1. Add assets/images/favicon.ico directly to the repo.
  2. Import it from the scientific-python-hugo-theme submodule.
  3. Point favicon: at the existing assets/images/logo.svg instead.

R8: Dead links on /contributors/getting-started/ fixed (change)

myst build --html surfaced broken internal links that were pre-existing on the
live Hugo site:

content/contributors/getting-started.md:23 Link has no URL: astropy
content/contributors/getting-started.md:23 Link has no URL: sunpy
content/contributors/getting-started.md:24 Link has no URL: numpy
content/contributors/getting-started.md:24 Link has no URL: scipy
content/contributors/getting-started.md:24 Link has no URL: matplotlib
content/contributors/getting-started.md:40 Link has no URL: integrated development environment

These are fixed in the PR.


Pre-existing non-issues (not regressions)

  • /about/governance/: empty stub (title: only) on both sites
  • /roadmap/: empty stub (title: only) on both sites

@lundybernard

Copy link
Copy Markdown
Author

Updated to account for the Cookie migration.

Ready for review

@lundybernard

Copy link
Copy Markdown
Author
  • Updated README.md with local build/preview docs
  • Added a more robust multithreaded local http server
  • Added make build-serve target

@henryiii

Copy link
Copy Markdown
Contributor

If this is an accurate preview, https://deploy-preview-315--learn-scientific-python-org.netlify.app/, the home page looks pretty bad, way more blank space, footer is particularly bad.

Screenshot 2026-07-25 at 12 57 38 AM Screenshot 2026-07-25 at 12 57 31 AM

@henryiii

Copy link
Copy Markdown
Contributor

docs/decisions feels like a ton of extra file that are not needed, they are historical. Once this is done, no one cares about the old site. Maybe these could be summarized into a single historical file, or attached to the PR text?

@drammock

Copy link
Copy Markdown
Member

footer is particularly bad.

@henryiii The footer is being fixed in scientific-python/scientific-python-myst-theme#7 which will be incorporated here once it's merged

@lundybernard

Copy link
Copy Markdown
Author

@henryiii on the ADRs, I can compress those docs significantly.
I don't think we need the PLAN.md at all, included in the PR because it was used for the migration process.
REQUIREMENTS.md was also used for guidance and validation during the migration, There's still some value there for validating that the change meets the requirements we set, we could move that info into the PR and out of the repo.

Most of the ADR docs are already fairly short, but could use some formatting cleanup (those tables are messy). I'll add a fixup commit with some changes when I have a few minutes.

lundybernard added a commit to lundybernard/learn.scientific-python.org that referenced this pull request Sep 15, 2026
The records served the planning phase of PR scientific-python#315 and stay in this
branch's history. README.md and content/myst.yml drop their pointers.

Refs scientific-python#315
Assisted-by: claude-code:claude-fable-5-1 [3M1LY]
lundybernard added a commit to lundybernard/learn.scientific-python.org that referenced this pull request Sep 15, 2026
The records served the planning phase of PR scientific-python#315 and stay in this
branch's history. README.md and content/myst.yml drop their pointers.

Refs scientific-python#315
Assisted-by: claude-code:claude-fable-5-1 [3M1LY]
@lundybernard

Copy link
Copy Markdown
Author
  • Consistent footers across learn sites

  • Header should show "Learn Scientific Python" in Lato font (see Development Guide)

The header should now show "Learn Scientific Python" (waiting for build to confirm), The font change will require a change to the theme template.

Consistent footers will require applying the copier template to the other sites, I can open a PR against the cookie site for starters.

lundybernard added a commit to lundybernard/learn.scientific-python.org that referenced this pull request Sep 15, 2026
The records served the planning phase of PR scientific-python#315 and stay in this
branch's history. README.md and content/myst.yml drop their pointers.

Refs scientific-python#315
Assisted-by: claude-code:claude-fable-5-1 [3M1LY]
@lundybernard

Copy link
Copy Markdown
Author

Requires: scientific-python/scientific-python-myst-theme#10

to prevent CI's prettier from reformatting after each update, I manually reformatted the files in this PR already.

@stefanv

stefanv commented Sep 16, 2026

Copy link
Copy Markdown
Member

Thanks, Lundy, this looks great!

There's one last issue with the width of the footer columns:

image

I am going to approve this; once Dan has taken a final look and the footer is fixed, I think we'll go ahead and merge.

@stefanv

stefanv commented Sep 16, 2026

Copy link
Copy Markdown
Member

One other thing: I don't see the social icon static files in the scientific-python-myst- theme template. As much as possible, this site should just be a content specialization of the copier version. Anything we can upstream to that theme, please do so.

@lundybernard

Copy link
Copy Markdown
Author

@stefanv

One other thing: I don't see the social icon static files in the scientific-python-myst- theme template. As much as possible, this site should just be a content specialization of the copier version. Anything we can upstream to that theme, please do so.

they are under template/assets (https://github.com/scientific-python/scientific-python-myst-theme/tree/main/template/assets/icons)

Copier vendors them in the target project.

Adds the full planning record for the Hugo → MyST-MD migration to
docs/decisions/0001-myst-migration/:

- REQUIREMENTS.md — what the migration must achieve and why
- PLAN.md — commit-by-commit 8-phase implementation sequence
- 0001–0007 ADR files — one decision per file, all Status: Proposed
- README.md — index of the above

ADR format is used so the decision rationale survives as a reviewable
archive. All ADRs are Proposed pending maintainer review; the plan and
requirements are the working basis for the migration work to follow.

Assisted-by: claude-code:claude-opus-4-8
- myst.yml: new; project.id, inline toc for content/ tree, excludes submodules
-  fixed project.id UUID, exclude submodule dirs (external-content/, themes/)
- .gitignore: add _build/ the MyST output directory
- ADR 0001: Accepted

Assisted-by: claude-code:claude-opus-4-8
_index.md is a Hugo idiom; MyST excludes _-prefixed files from
auto-discovery. Renames done before content changes so all later
commits reference the final filenames.

Assisted-by: claude-code:claude-opus-4-8
Assisted-by: claude-code:claude-opus-4-8
Mapping (per ADR 0002):
  {{< admonition warning >}}…{{< /admonition >}}  →  :::{warning}…:::
  {{< admonition note >}}…{{< /admonition >}}     →  :::{note}…:::

Assisted-by: claude-code:claude-opus-4-8
shortcutDepth was a Hugo theme option controlling sidebar depth.
MyST has no equivalent and warns on unknown frontmatter keys.

Assisted-by: claude-code:claude-opus-4-8
Hugo silently rendered [text]() as href=""; MyST raises build errors.
Added URLs for astropy, sunpy, numpy, scipy, matplotlib, and
a Wikipedia link for "integrated development environment".

Assisted-by: claude-code:claude-opus-4-8
- html: hugo → myst build --html (output now in _build/html/)
- html-all: copy _build/html/ to public/ then build external content
- serve: hugo server → myst start
- clean: also removes _build/

Assisted-by: claude-code:claude-opus-4-8
Remove Hugo/Dart Sass toolchain (HUGO_VERSION, DART_SASS_VERSION,
DART_SASS_URL env vars and the curl/tar/PATH install block).
MyST ships pre-built CSS; no Sass compilation step required.

Add `pip install mystmd` before `make html-all`. Keep PYTHON_VERSION,
publish = "public", and netlify-plugin-checklinks unchanged.

Assisted-by: claude-code:claude-opus-4-8
Port description, nav, domain, and logo from config.yaml.
Rename static/ → assets/ (Hugo directory convention; MyST does
not serve static/ automatically — assets/ is the expected path).

No dark logo or favicon: neither existed in the Hugo static/ dir;
MyST supplies a default favicon. Footer/quicklinks deferred per ADR 0005.

Assisted-by: claude-code:claude-opus-4-8
- Delete config.yaml (metadata ported to myst.yml in previous commit)
- Remove scientific-python-hugo-theme submodule (only consumed by Hugo;
  other SP repos vendor their own copy — ADR 0003)
- Drop .hugo* and resources/ from .gitignore; both are Hugo-specific.
  _build/ was already present; public/ kept for html-all output.

Assisted-by: claude-code:claude-opus-4-8
Vendor scientific-python/scientific-python-myst-theme at 9002ff6 with
copier. The footer grid reads its links and social icons from a JSON
file through the footer-items.mjs plugin.

The template ships the scientific-python.org link set, whose relative
paths do not exist on this site. footer_items.json carries the links
and icons from the Hugo footer on main instead, plus the Bluesky
account the main site links: About and Roadmap stay local, the other
five links point at scientific-python.org.

Assisted-by: claude-code:claude-opus-4-8
Assisted-by: claude-code:claude-fable-5-1 [3M1LY]
- Document build/preview process in README
- Document ADRs in README
- add small threaded server to scripts/serve.py

Assisted-by: claude-code:claude-opus-4-8
The records served the planning phase of PR scientific-python#315 and stay in this
branch's history. README.md and content/myst.yml drop their pointers.

Refs scientific-python#315
Assisted-by: claude-code:claude-fable-5-1 [3M1LY]
@lundybernard

lundybernard commented Sep 16, 2026

Copy link
Copy Markdown
Author

There's one last issue with the width of the footer columns:
image

I added a fixup commit to the end of the branch to address this, the preview looks good to me now.

up-streamed the change to the theme in this PR: scientific-python/scientific-python-myst-theme#12

If it looks good to y'all let me know and I'll fixup the history.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert to MySTMD & enable PR previews on RTD

4 participants