Context
The customer
Consider the following: a user has a site on Wix, but wants to use a third-party service to provide translations (the why is not relevant now, suffice it to say that Wix Multilingual is not an option for this user). This service acts as a proxy in front of Wix, and proxies the original website on a different URL.
The architecture
Let’s say the domain example.com
is connected to the Wix site in question, and the customer wants to serve translations under /ja/
. They have connected a CDN that separates requests based on the path, and sends the /ja/
prefix towards the proxy service, sending everything else towards Wix directly.
Now, the proxy service will initiate a second request towards Wix separate of the original, with the path remapped to the correct resource in Wix, requesting the English content.
To put it all together, because a picture is worth a thousand words:
+------+
example.com/foo | | +------+
+--------------->| +------>| Wix |
| | | +------+
Visitor | CDN | ^
| | | | example.com/foo
| | | +----+-----+
+--------------->| +---->| Proxy |
example.com/ja/foo +------+ +----------+
What is important to note here is that Wix will only ever see requests for the original resources. This will come into play soon.
The problem
With the setup above, as long as the visitor is looking at the original language, everything is fine. But the moment they try loading anything on the translated site, Wix throws an error and just fails to load anything.
The problem is that when the Wix engine is initializing, the route info is constructed incorrectly. Within routerInit.ts
, there’s the following function:
const getInitialNavigationUrl = (window: BrowserWindow, viewerModel: ViewerModel) => {
if (isSSR(window) || viewerModel.rendererType === 'react') {
return viewerModel.requestUrl
}
// When the site is being viewed in Google Translate (e.g: https://ssrdev-wixsite-com.translate.goog/button-wixcode?_x_tr_sl=en&_x_tr_tl=iw&_x_tr_hl=en-US)
// Or Google cached copy (e.g: https://webcache.googleusercontent.com/search?q=cache:cqru0HcBGaEJ:https://www.wix.com/+&cd=1&hl=en&ct=clnk&gl=il)
if (
window.location.host.includes('translate.goog') ||
window.location.host.includes('webcache.googleusercontent.com')
) {
return viewerModel.requestUrl
}
// In the browser we take the URL from the address bar in order to support hash
return window.location.href
}
Because this takes the entire href
, using a path prefix - or even a different subdomain, for that matter - will cause the router to be assembled incorrectly and fail to load any content. However, the viewerModel.requestUrl
field does have the correct value, indicating that the server is aware of the resource requested.
If I use the browser dev tools to suspend the script and overwrite the URL returned from this function, the page is rendered correctly, and the translations work just fine, but obviously, this is no solution.
Furthermore, later on in the lifecycle, there’s a call to history.pushState()
- for sake of simplicity after re-parsing the URL - so that even if the page is loaded correctly, the visible address in the browser is replaced with the incorrect one…
The Question
The million-dollar question: would it be possible to create a configuration flag, a switch, something that tells the router to disregard window.location.href
and use the data from viewerModel.requestUrl
for assembling the router, as well as for the eventual pushState
call that overwrites the displayed URL?