Skip to content
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

Provide a 404 page #72

Open
jimporter opened this issue Sep 22, 2021 · 6 comments
Open

Provide a 404 page #72

jimporter opened this issue Sep 22, 2021 · 6 comments
Milestone

Comments

@jimporter
Copy link
Owner

Currently, there's no 404 page (since MkDocs' 404.html ends up in a subdirectory). We should fix this and possibly include some basic logic to redirect users to the right page.

@caarlos0
Copy link

moreover, would be nice to have something it redirect to the versioned page...

e.g., I go to mysite.com/subpage, it gets redirected to mysite.com/latest/subpage - that way its easier to migrate from not having versioned docs...

@jorisroovers
Copy link

Hi, thanks for creating Mike!

I’m looking to adopt it for gitlint (very recently adopted Material for Mkdocs, after using vanilla mkdocs for many years).

e.g., I go to mysite.com/subpage, it gets redirected to mysite.com/latest/subpage - that way its easier to migrate from not having versioned docs...

This is something I’d like to have, to avoid breaking old URLs.

I’d happily help implement this if you’re accepting PRs for it? If so, could use a pointer on how to get started.

Thanks!

@jimporter
Copy link
Owner Author

It shouldn't actually be necessary for mike to do anything particular here: all you need to do is add your own 404.html to your gh-pages branch, and then that 404 page should get used properly by Github's static webserver. The tricky part is figuring out how to perform the redirects correctly. You probably want two main behaviors:

  • Redirect from example.com/some-page to example.com/default-version/some-page if the latter exists, else to example.com
  • Redirect from example.com/some-version/missing-page to example.com/some-version if the latter exists, else to example.com

This probably means writing some JS to do that, which is annoying since you can't unconditionally redirect or else you could end up in a redirect loop.

@jimporter
Copy link
Owner Author

jimporter commented May 12, 2023

A further limitation to putting this in mike is that mike currently doesn't record the default-version in a place that's easy to parse back out, so we'd need some kind of solution there (though that could be "generate 404.html at the same time as the main index.html").

Speaking of index.html, there's also a broader question about what the most usable way to manage cross-version files like that is. I'm not sure what the answer is though... maybe just create a mike init command that does one-time initial setup (sort of like an enhanced/expanded version of mike set-default). That would solve all of this fairly neatly, though it's a bit more complex for the user than having it all work automagically.

@jorisroovers
Copy link

This probably means writing some JS to do that, which is annoying since you can't unconditionally redirect or else you could end up in a redirect loop.

Got it, thanks! Let me give this a try :-)

@jorisroovers
Copy link

Ok, I gave this an attempt, adding the 404.html below to my gh-pages branch. This seems to be working on https://jorisroovers.com/gitlint/

<script>
    // Check if the current path is versioned, if not, redirect to the default versioned path
    const versions = ["0.19.x", "latest"]
    const defaultVersion = "latest"
    const basePath = "/gitlint"
    const targetRedirectPath = "404" // path to redirect to, relative to basePath

    // if path starts with version, redirect to versioned 404
    let foundVersion = false
    versions.forEach(version => {
        const versionedPath = `${basePath}/${version}`;
        if (window.location.pathname.startsWith(versionedPath)) {
             // we need this foundVersion guard because the browser is fast and
             // will keep the executing code below until the redirect happens
            foundVersion = true;
            window.location.href = `${versionedPath}/${targetRedirectPath}`
        }
    });

    // if path doesn't start with any version, redirect to defaultVersion
    // Replace it in href, so we keep hashes and query params
    // Only replace first occurence of basePath
    if (!foundVersion){
        window.location.href = window.location.href.replace(basePath, `${basePath}/${defaultVersion}`)
    }
</script>

If you’d want to make something like this part of mike, I think you indeed would need to generate this file with an init command or something.

While it might be possible to parse some the variables defined at the start from the active path rather than hardcoding (configuring) them, I think it gets tricky to figure out which parts of the URI are the basePath, the version and the remainder of the URI.

Wrt the variables at the top:

  • versions: these could be parsed from versions.json in javascript, although a bit more overhead.
  • defaultVersion: like you already mentioned, this would need to be made available. Perhaps the versions.json format could be extended to record this value.
  • basePath: this could be configurable in yaml (only needed when (re)generating the 404.html)
  • targetRedirectPath: this could be configurable in yaml (only needed when (re)generating the 404.html)

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

No branches or pull requests

3 participants