Skip to content

Conversation

@cubernetes
Copy link

@cubernetes cubernetes commented Sep 19, 2025

site_url has to end with a trailing slash, because when MkDocs processes the Jinja2 templates, it will embed a script tag into the final html:

<script id="__config" type="application/json">{"base": "/some/path/4.1.1", ...}</script>

The JS-relevant part of mike then handles this as follows fetch(ABS_BASE_URL + "../versions.json")
or, if you look at the actual js-bundle:
new URL("../versions.json", t.base)

And if t.base doesn't end with a trailing slash, the last component is completely ignored, which is obviously not what we want:

new URL("../versions.json", "https://example.com/some/path/4.1.1")
// expected: https://example.com/some/path/versions.json
// actual:   https://example.com/some/versions.json

Note that I'm not well versed in the MkDocs/mike codebases, I might've overlooked something, but my gut feeling says this might be correct

@jimporter
Copy link
Owner

jimporter commented Sep 19, 2025

Thanks for reporting this. As far as I can tell, both MkDocs and the built-in theme support in mike handle this properly. What theme are you using? From this bit:

new URL("../versions.json", t.base)

it looks like you might be using the Material theme, so in that case, I think this might be a bug over there.

@cubernetes
Copy link
Author

cubernetes commented Sep 19, 2025

It's a chain of issues. It starts with this PR.

Then, the config that mike generates is passed to mkdocs:
https://github.com/mkdocs/mkdocs/blob/master/mkdocs/commands/build.py#L74

The base_url is set directly to site_url for error pages, so this issues only happens with those.

Then, in material for mkdocs, the base_url is embedded as is into a script config inside the base template (it has the id __config):
https://github.com/squidfunk/mkdocs-material/blob/master/material/templates/base.html#L227

and a version controlled js-bundle is also included in that base template:
https://github.com/squidfunk/mkdocs-material/blob/master/material/templates/base.html#L248

That bundle contains the following snippets of javascript, executed chronologically:

var Ca=R("#__config")
St=JSON.parse(Ca.textContent)
function xe(){return St}
t=xe()
r=je(new URL("../versions.json",t.base))

As you can see, it calls new URL() with t.base, which still doesn't have a trailing slash.

I'm not sure where I should go next. I could go to mkdocs, and file a PR that adds a trailing slash there (this line), or I could go to material for mkdocs and file a PR there, that adds a trailing slash to t.base (or St.base to be precise, or better yet, in the original source of that bundle whereever that is).

What do you recommend? I reckoned that this is the appropriate place to file the PR

@jimporter
Copy link
Owner

@cubernetes This issue could come up without mike being involved (e.g. if an MkDocs user manually set site_url to https://example.com/foo), so I think it'd be worth filing a bug in the MkDocs project. It would probably make sense for MkDocs to normalize the site URL before doing anything with it, or at least to error out if the user-supplied URL doesn't have a trailing slash.

@cubernetes
Copy link
Author

cubernetes commented Sep 21, 2025

Hm, I'm not entirely sure, because if I have a simple mkdocs.yaml:

...
site_url: http://localhost:8080/some/path
theme:
    name: material
...

Then the 404 page always has <script id="__config" type="application/json">{"base": "/some/path/", ...}</script> (note the trailing slash). Ergo, mkdocs always ensures there's a trailing slash inside the __config thing, which is part of the material theme.

However, as soon as I use mike deploy, that trailing slash is never there :/, because mike adjusts the config object after mkdocs has done it's processing (which, afaik, entails ensuring there's a trailing slash)

@jimporter
Copy link
Owner

jimporter commented Sep 21, 2025

Oh, I see. The MkDocs validation runs earlier than I thought, and the on_config hook requires plugin authors (i.e. me) to validate any changes to the configuration manually.

I'd still lean towards this being a bug in MkDocs, since it would probably be more robust to append the trailing slash to the site_url after on_config. The current way requires any plugin author in a similar situation to be careful about this, when MkDocs could be handling it on its own in all cases. I'll file an upstream issue and see what the MkDocs maintainers think.

@cubernetes
Copy link
Author

Awesome, thanks a lot!

`site_url` has to end with a trailing slash, because when MkDocs processes the Jinja2 templates, it will embed a script tag into the final html:
```js
<script id="__config" type="application/json">{"base": "/some/path/4.1.1", ...}</script>
```

The JS-relevant part of mike then handles this as follows
`fetch(ABS_BASE_URL + "../versions.json")`
or, if you look at the actual js-bundle:
`new URL("../versions.json", t.base)`

And if `t.base` doesn't end with a trailing slash, the last component is completely ignored, which is obviously not what we want.
@cubernetes cubernetes force-pushed the cubernetes-site_url-trailing-slash branch from 896f62a to ff13fbe Compare September 22, 2025 07:37
@cubernetes
Copy link
Author

FYI: I added slashes to the unit tests, I think you have to approve the workflow once more if you're interested in the test outputs now, unless you're waiting for answers in the mkdocs issue

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