Skip to content

Fix internal links in the documentation #4659

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 18, 2025

Conversation

niooss-ledger
Copy link
Contributor

When Sphinx encounter links to neighbor files using .html extension, it consider it as a section reference to the same file. For example, doc/endpoint/schemas.md contains:

e.g. for [newtype](integrations.html#newtype-integration) you'll

Sphinx compiles the link to:

<a class="reference internal" href="#integrations.html#newtype-integration">
<span class="xref myst">newtype</span>
</a>

In practice, when visiting
https://tapir.softwaremill.com/en/latest/endpoint/schemas.html and clicking on "newtype", the browser goes to
https://tapir.softwaremill.com/en/latest/endpoint/schemas.html#integrations.html#newtype-integration instead of
https://tapir.softwaremill.com/en/latest/endpoint/integrations.html#newtype-integration

Using integrations.md in the Markdown link makes Sphinx understand the link is referencing another file. The generated HTML code contains the right link to integrations.html:

<a class="reference internal" href="integrations.html#newtype-integration">

Fix this issue every place it occurs in the documentation pages.

Also replace absolute links to https://tapir.softwaremill.com/en/latest/ with relative ones. This makes it easier to generate self-contained documentation of past releases (where links do not target "latest").

Some links triggered myst.xref_missing errors. For example:

target/tapir-doc/endpoint/oneof.md:12: WARNING: local id not found
in doc 'endpoint/schemas': 'sealed-traits-coproducts' [myst.xref_missing]

The generated HTML of doc/endpoint/schemas.md correctly defined the anchor sealed-traits-coproducts:

<section id="sealed-traits-coproducts">
<h2>Sealed traits / coproducts

However MyST generates slightly different slugs:

$ myst-anchors -l 2 target/tapir-doc/endpoint/schemas.md
...
<h2 id="sealed-traits--coproducts"></h2>

Using schema.md#sealed-traits--coproducts in oneof.md fixed the issue and correctly generated a link to
schemas.html#sealed-traits-coproducts.

By the way, generating MyST identifiers for Markdown sections requires setting myst_heading_anchors = 3 in the Sphinx configuration, cf. https://myst-parser.readthedocs.io/en/latest/syntax/cross-referencing.html#implicit-targets

To test building the documentation, I used a clean Ubuntu 24.04 container where I ran:

apt update
apt install -y libidn2-dev libcurl3-dev curl clang python3-sphinx python-is-python3 python3-myst-parser python3-sphinx-rtd-theme
curl -fL https://github.com/coursier/coursier/releases/latest/download/cs-x86_64-pc-linux.gz | gzip -d > cs
chmod +x cs && ./cs setup --jvm temurin:1.21 && . ~/.profile

cd /tapir && sbt -J-Xms4g -J-Xmx4g -v compileDocumentation
make -C /tapir/target/tapir-doc/ html

After this, I browser target/tapir-doc/_build/html/index.html and checked the links were fixed.

When Sphinx encounter links to neighbor files using `.html` extension,
it consider it as a section reference to the same file. For example,
doc/endpoint/schemas.md contains:

    e.g. for [newtype](integrations.html#newtype-integration) you'll

Sphinx compiles the link to:

    <a class="reference internal" href="#integrations.html#newtype-integration">
    <span class="xref myst">newtype</span>
    </a>

In practice, when visiting
https://tapir.softwaremill.com/en/latest/endpoint/schemas.html and
clicking on "newtype", the browser goes to
https://tapir.softwaremill.com/en/latest/endpoint/schemas.html#integrations.html#newtype-integration
instead of
https://tapir.softwaremill.com/en/latest/endpoint/integrations.html#newtype-integration

Using `integrations.md` in the Markdown link makes Sphinx understand the
link is referencing another file. The generated HTML code contains the
right link to `integrations.html`:

    <a class="reference internal" href="integrations.html#newtype-integration">

Fix this issue every place it occurs in the documentation pages.

Also replace absolute links to https://tapir.softwaremill.com/en/latest/
with relative ones. This makes it easier to generate self-contained
documentation of past releases (where links do not target "latest").

Some links triggered myst.xref_missing errors. For example:

    target/tapir-doc/endpoint/oneof.md:12: WARNING: local id not found
    in doc 'endpoint/schemas': 'sealed-traits-coproducts' [myst.xref_missing]

The generated HTML of `doc/endpoint/schemas.md` correctly defined the
anchor `sealed-traits-coproducts`:

    <section id="sealed-traits-coproducts">
    <h2>Sealed traits / coproducts

However MyST generates slightly different slugs:

    $ myst-anchors -l 2 target/tapir-doc/endpoint/schemas.md
    ...
    <h2 id="sealed-traits--coproducts"></h2>

Using `schema.md#sealed-traits--coproducts` in `oneof.md` fixed the
issue and correctly generated a link to
`schemas.html#sealed-traits-coproducts`.

By the way, generating MyST identifiers for Markdown sections requires
setting `myst_heading_anchors = 3` in the Sphinx configuration, cf.
https://myst-parser.readthedocs.io/en/latest/syntax/cross-referencing.html#implicit-targets
@adamw adamw merged commit a62644b into softwaremill:master Jun 18, 2025
27 checks passed
@adamw
Copy link
Member

adamw commented Jun 18, 2025

Thanks! Very nicely described - and much needed docs hygiene :)

@niooss-ledger niooss-ledger deleted the fix-documentation-links branch June 18, 2025 10:55
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.

2 participants