SSR Migration and Routing Configuration for Taobao Car Detail Pages
The team merged Taobao car detail page SSR and CSR into a single repository by adding an "ssr": true flag, aligning routing across src/pages, app.json, and render functions, ensuring PAGE_NAME matches app.json names, mocking browser globals for Node builds, moving metas and scripts to documents, and dynamically overriding the public path to load pre‑release assets, thereby cutting double maintenance and simplifying deployment.
In the previous article "SSR transformation practice of Taobao car detail page", the team introduced a separate SSR application to avoid affecting the online CSR project.
When the CSR repository changes, the SSR application also needs to be updated, which doubles the maintenance cost for code, testing, CI and release. To reduce this, the team tried to keep SSR and CSR in sync by adding an "ssr": true flag in build.json , but the internal platform did not support a single repository serving two applications.
By publishing the SSR application together with CSR links, only one application needs to be maintained. The migration process involved aligning routing configurations.
Routing configuration
Four places affect routing in an SSR app:
Page source directory (usually src/pages/ ).
app.json routes configuration.
SSR render function directory ( src/apis/render/ ).
The PAGE_NAME used inside the render function.
The PAGE_NAME is not the default directory name; it must match the name field in app.json so that the server can locate the built page.
Example of app.json routes:
{
"routes": [
{ "name": "myhome", "source": "pages/Home/index" },
{ "name": "pages/about", "source": "pages/About/index" }
]
}Render functions receive PAGE_NAME and call useSSRRenderer(PAGE_NAME) to generate the document.
Environment simulation
During pre‑release builds, a debugging plugin injected variables on window (e.g., window.__mito_result = 'something' ) but accessed them without the window prefix, causing ReferenceError: __mito_result is not defined in the Node environment. The solution was to enable mock browser environment in build.json and pass a list of variables to useSSRRenderer :
// build.json
{
"web": {
"ssr": {
"mockBrowserEnv": true
}
}
}
// render function
export default withController({
middleware: [downgradeOnError(PAGE_NAME), phaIntercept(PAGE_NAME)],
}, async () => {
const ssrRenderer = await useSSRRenderer(PAGE_NAME, {
mockBrowserEnv: true,
globalVariableNameList: ['__mito_data', '__mito_result'],
browserEnv: {}
});
});The framework wraps the page code in a function whose parameters are the mocked globals, allowing the page to run without real window .
Media and script injection
In CSR, metas and scripts in app.json are inserted into the document. In SSR they must be moved to the documents section, and scripts should be placed via dangerouslySetInnerHTML above the <Root /> component.
Resource path handling
SSR does not rebuild static assets, so pre‑release documents still reference the production CDN ( g.alicdn.com ). By overriding __webpack_public_path__ at runtime, the SSR server can point to the pre‑release CDN ( dev.alicdn.com ), ensuring resources load correctly.
Summary
The migration clarified the relationship between page source, app.json routing, render function location, and PAGE_NAME . It also highlighted the importance of environment mocking, proper script injection, and dynamic resource paths when operating both CSR and SSR in a single repository.
DaTaobao Tech
Official account of DaTaobao Technology
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.