gTranslate through TLDs: Subfolder magic with mod_rewrite

Anyone who knows me knows that I’m pretty shit with DevOps. However, I’ve finally bitten the bullet and started learning. I did my first bit of Ansible last week, and this week I’ve approached an interesting problem. I’m fairly new to this stuff but I’m hoping the few hours I spent coming up with this solution might save someone else some time later down the line.

A client came to me wanting to use the gTranslate plugin – nothing unusual there, it’s pretty handy. However, they had a premium plan and wanted to route each language through their own TLDs, which is only officially supported by routing through their nameservers. Routing through their servers comes with some risks such as downtime, which the client wasn’t willing to accept.

Enter the mod_rewrite magic! We configured the plugin using subdirectory routes – e.g. example.co.uk/hello and example.co.uk/fr/bonjour

The initial setup was quick and painless. Run through a quick wizard which configures the site. No problem there.

The plugin adds some stuff to the .htaccess file which proxies routes through a page included in the plugin. Specifically:

/content/plugins/google-language-translator/url_addon/gtranslate.php?glang={language}&gurl={url}

So I lifted this and proxied our TLDs through it.

Proxying the TLDs through to the subfolders

RewriteCond %{SERVER_NAME} =example.fr
RewriteRule ^(.*)$ https://example.co.uk/content/plugins/google-language-translator/url_addon/gtranslate.php?glang=fr&gurl=$1 [NC,P,L,QSA]T

What we’re essentially saying here is whenever we match the .fr TLD, we proxy it through the gTranslate script. Unfortunately, this needs to be repeated for each TLD.

The P flag is essential here – it needs to proxy the URL, without redirecting! We also need

However, there’s another issue now. We now have duplicate content on both example.co.uk/fr/slug and example.fr/slug

To get around this, an additional redirect was needed.

Redirecting the subfolders to the TLDs

This turned out to be a little more concise. We can take the language code directly and lob it into the TLD:

RewriteCond %{SERVER_NAME} =example.co.uk
RewriteRule ^(fr|de|pl|ru|it|es)/(.*)$ https://example.$1/$2 [R=301,L,NC]

I’m sure there’s probably others, but we found an exception to this rule with Japanese – gTranslate uses ja, whereas the TLD is .jp. So it needed its own rule:

RewriteCond %{SERVER_NAME} =example.co.uk
RewriteRule ^(ja)/(.*)$ https://example.jp/$2 [R=301,L,NC]

Lastly, we encountered some CORS issues with accessing certain media (e.g. fonts) through CSS files because they were referencing the primary domain. To get around this, we popped a bit of magic into the vhost config.

Allowing specific routes through CORS

This was a handy script we found on StackOverflow – we only found the issue on fonts being referenced through the primary WP url (example.co.uk), so we simply added an Access-Control-Allow-Origin header for those routes:

    <FilesMatch "\.(ttf|otf|eot|woff|woff2)$">
        <IfModule mod_headers.c>
            SetEnvIf Origin "http(s)?://(www\.)?example.(co.uk|jp|de|pl|ru|fr|it|es)$" AccessControlAllowOrigin=$0
            Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
            Header merge Vary Origin
        </IfModule>
    </FilesMatch>

It took a few hours to come up with this solution, so I’m hoping it might save someone else some time!

Leave a Comment