vuepress / vuepress-community

:bulb: Community supported ecosystem for VuePress
https://vuepress-community.netlify.app
MIT License
81 stars 62 forks source link

[Question] vuepress-plugin-redirect locale redirects and Nginx #43

Closed TiEul closed 4 years ago

TiEul commented 4 years ago

I have answered my own question

Obviously 10 minutes after posting this I have figured it out myself after having been at it for quite some while. This is for all the people finding this via some web search because I could not find anything.

I wanted VuePress to run with Nginx, SSL and automatic language redirects. Here is the relevant part of my Nginx configuration, including letsencrypt and an automatic redirect from HTTP to HTTPS:

server {
    listen 80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

server {
        listen 443 default_server ssl;
        root /var/www/mydomain.xyz/docs/.vuepress/dist;
        server_name mydomain.xyz;
        index /en/index.html;

        ssl_certificate     /etc/letsencrypt/live/mydomain.xyz/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/mydomain.xyz/privkey.pem;

        location / {
                try_files $uri $uri/ /en/index.html /404.html;
        }
}

This was what I was missing mainly:

location / {
                try_files $uri $uri/ /en/index.html /404.html;
        }

You want try_files to just point at the index.html in your default language followed by the 404.html in the root directory of VuePress, then it works just fine. If you are not using any automatic language redirects, just use this config and it will work fine:

location / {
                try_files $uri $uri/ index.html /404.html;
        }

Environment

What's your question? [ANSWERED MYSELF, IGNORE BELOW]

I am trying to get vuepress-plugin-redirect with locales: true to work in combination with Nginx but I am facing multiple problems. I am actually not sure if it can be fixed by changing the Nginx configuration or if this requires some sort of fix in VuePress itself.

As per the official redirect docs I have configured my docs directory so that it includes nothing but language folders. My docs directly looks like this, no other files are present as I want VuePress to automatically redirect the user to the correct language:

docs/.vuepress/
docs/en/
docs/de/

This means the built dist directory looks like this:

dist/assets/
dist/en/
dist/en/index.html
dist/en/<All English Docs>
dist/de/
dist/de/index.html
dist/de/<All German Docs>

However, that means the root directory of dist has no index.html:

dist/404.html
dist/favicon.ico
dist/robots.txt
dist/sitemap.xml

This means I am not able to point nginx at a "language neutral" index.html file:

server {
        listen 443 default_server ssl;
    root /var/www/mydomain.test/docs/.vuepress/dist;
        server_name mydomain.test;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

}

The consequence of that is that just going to the domain will result in a 403 error as no file can be found in the directory by nginx. The only way this can be avoided is to forcefully select a directory like that but that is not what I want because it completely beats the purpose of the redirect plugin:

    location = / {  
            return 301 /en/;
    }

Any URLs that do not specify a language (/some/page.html rather than /en/some/page.html) will also not work and cause 500 Internal Server Errors like this:

*10 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 79.237.53.16, server: xxx request: "GET /some/pagehtml HTTP/1.1", host: xxx

Am I missing anything? Is it possible to create a "neutral" index.html or is there some other fancy way I can get this to work with Nginx? I guess part of the problem is that I don't fully understand some of the VuePress magic with the entry point. I don't know how VuePress handles this locally in the dev environment but it works all well there.