Redirect whole site to subfolder except static assets like CSS/JS

Hi!

So we’re currently in the process of making our site multi-lingual. Our plan is to move to sub-folder based language-urls: my-site.com becomes my-site.com/en, my-site.com/cool-stuff becomes my-site.com/en/cool-stuff, etc.

This more or less works if we add language-based redirects to our Netlify config:

/*  /en/:splat Language=en

But now everything gets redirected (incl. CSS and JavaScript files which live in the root of the website and aren’t localized).

Is there a way to get around this?

Thanks in advance.

Flo

Hiya, @flo!

While in theory that would work as you’re intending since /asset.png would be an existing file and you don’t use the syntax to force redirection even when it would shadow a file (cf https://www.netlify.com/docs/redirects/#note-on-shadowing), in practice, language redirects do behave as though they were forced. While this seems to be as designed even though it feels to me like a bug, it makes your use case a bit harder to accomplish

So, you have a few options I can think of:

  1. decouple your assets from your main site (have e.g. a “assets.mysite.com” under which you serve all assets). This could be as simple as a second deploy of your code with a different base directory (/assets) or even just a straight second deploy WITHOUT that redirect to which you could link at the same path (<img src=/asset.png> becomes <img src=https://assets.mysite.com/asset.png>)
  2. duplicate your assets into each language directory. Inelegant, but if you have only a handful, might be simpler.

I am sure there are other options but those are the two I could come up with easily.

I have attached this thread to the feature request to improve the handling of language redirects to NOT always act as forced, so I can follow up here in case that feature changes behavior.

Hi @fool,

Thanks for your response. We went with your second suggestion and it seems to work fine. But just out of curiousity, have you already fixed the shadowing issue? Because I tried it on a test-environment and it seems to work without the work-around.

Best,
Flo

It’s not fixed, but it isn’t consistently broken either in our testing - a lot has to do with whether anyone has already visited the site on a CDN node since last deploy - we’ll often cache the first thing that comes through. If the first request is for https://yourlanguagegatedsite.com/asset.png that will likely work, but if it’s for a path that would require a redirect, that redirect may get cached instead.

The fix you’ve implemented will work either way - whether it happens to work as you’re hoping, or not :slight_smile:

@flo @fool I’ve been seeing the same bug but I’ve worked out another workaround I thought it would be useful to share.

[[redirects]]
from = "/static/*"
to = "/static/:splat"
status = 200
force = true
    
[[redirects]]
from = "/*"
to = "/.netlify/functions/hello/"
status = 200
force = false

If I had just the second redirect it would end up redirecting the static files despite the documentation on shadowing saying it should not. Adding a pointless static -> static folder redirect which should do nothing seems to trick netlify into leaving that folder alone.

thank you for sharing, @dalejefferson_rnf!

As an update to anyone watching this thread or finding it later: language redirects should no longer act as “forced” unless you explicitly configure it (force="true" in netlify.toml or using the ! in _redirects).

Hi,

I tried to follow the trick @dalejefferson_rnf suggested , but it didnt work

[[redirects]]
  from = "/*"
  to = "/build/dokka/html/kotlin-unsigned"
  status = 200

[[redirects]]
  from = "/build/dokka/html/images/*"
  to = "/build/dokka/html/images/:splat"
  status = 200
  force = true

# same for /scripts and /styles

What am I doing wrong?

Hi, @elect86, to answer we need a real URL which should redirect and does not so we can research the issue and find out what is happening. Would you please send us a real URL which should redirect but does not?

@luke

Sure, url is https://unsigned.netlify.app, repo is https://github.com/kotlin-graphics/kotlin-unsigned (if you want to check configuration under netlify.toml), but the uploaded file are generated on build, you can find them here

Hi, @elect86. The redirect rule in netlify.toml is this:

[[redirects]]
  from = "/"
  to = "/build/dokka/html/kotlin-unsigned"

I do see this redirect working when I test:

$ curl -svo /dev/null https://unsigned.netlify.app/  2>&1 | egrep '< (HTTP|location)'
< HTTP/2 301
< location: /build/dokka/html/kotlin-unsigned

This is a 301 redirect which is how the rule is currently written (because if no status is defined the rule defaults to a 301 redirect).

Note, the references to some of the other files in the HTML being redirected to are relative paths. They being with ../ which won’t work if you 200 proxy the path / to this page. It would break all those <script> tag src links. With the 301 the path is unchanged so those links work.

    <script type="text/javascript" src="../scripts/navigationLoader.js" async="async"></script>
    <script type="text/javascript" src="../scripts/platformContentHandler.js" async="async"></script>
    <script type="text/javascript" src="../scripts/sourceset_dependencies.js" async="async"></script>
    <script type="text/javascript" src="../scripts/clipboard.js" async="async"></script>

If there are other questions about this, please let us know.

So there is no way to have clean url with relative paths? Have I understood right?

Hi, @elect86. Basically, yes.

If you proxy from https://unsigned.netlify.app/ then the path portion of the URL is just /. If the path is / then the path ../scripts/navigationLoader.js doesn’t exist because ../ means “up one directory” and there is no directory above /.

1 Like

If I replace manually all the relative paths with an absolute one, then I should be ready to go then, or?

Sounds good to me, @elect86!

1 Like