Skip to content

[web] add --static-assets-url argument to build web command #171637

@micaelcid

Description

@micaelcid

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterplatform-webWeb applications specificallyteam-webOwned by Web platform teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-webTriaged by Web platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions