-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Use case
In enterprise-level environments, it's a standard practice to serve static assets from a centralized CDN for performance, cost, and infrastructure optimization - as it may have dozens of webapps. This means an application hosted at https://app.company.com might need to load its compiled JavaScript, fonts, and other assets from a different origin, such as https://static.company.com/some-webapp/.
Modern web frameworks like Next.js support this out-of-the-box via an assetPrefix configuration, which allows developers to specify a full URL for assets.
Flutter web currently lacks a direct, first-party mechanism to configure a separate URL for its static assets. The existing --base-href flag is unsuitable for this purpose as it is designed for URL path routing (e.g., /my-app/) and does not accept full URLs for different domains.
This limitation forces developers to create and maintain custom pre-build scripts to manually inject the asset URL into the index.html file, adding complexity and maintenance overhead to the deployment pipeline (which is what we did and it’s working pretty fine in production).
Proposal
I propose introducing a new argument to the flutter build web command, such as --static-assets-url (already opened a PR).
This argument would accept a full URL string ending with / as its value. During the build process, the Flutter tool would use this value to replace a dedicated placeholder within the web/index.html file (inspired by --base-href approach).
Example Implementation:
A developer would modify their web/index.html to use a new placeholder, for instance, $FLUTTER_STATIC_ASSETS_URL:
...
<body>
<script>
{{flutter_js}}
{{flutter_build_config}}
_flutter.loader.load({
config: {
entryPointBaseUrl: "$FLUTTER_STATIC_ASSETS_URL",
},
onEntrypointLoaded: async function (engineInitializer) {
const appRunner = await engineInitializer.initializeEngine({
assetBase: "$FLUTTER_STATIC_ASSETS_URL",
});
await appRunner.runApp();
},
});
</script>
</body>
...The build command would be run with the new flag: flutter build web --static-assets-url="https://static.company.com/some-webapp/“ - and the resulting build/web/index.html would have the placeholder replaced:
...
<body>
<script>
{{flutter_js}}
{{flutter_build_config}}
_flutter.loader.load({
config: {
entryPointBaseUrl: "https://static.company.com/some-webapp/",
},
onEntrypointLoaded: async function (engineInitializer) {
const appRunner = await engineInitializer.initializeEngine({
assetBase: "https://static.company.com/some-webapp/",
});
await appRunner.runApp();
},
});
</script>
</body>
...This feature would provide a clean, officially supported solution for serving Flutter web assets from a CDN, aligning Flutter's capabilities with established web development practices and making it more robust for enterprise-level use cases.