Upload source maps for Angular

Contents

Do not inject after an Angular service-worker build

posthog-cli sourcemap inject changes JavaScript files. If you run it after Angular creates ngsw.json, the service-worker hashes no longer match and Angular rejects the application update. Use the build plugin below so Angular hashes the final JavaScript.

Setup

  1. Install the PostHog CLI

    Required

    Install posthog-cli:

    npm install -g @posthog/cli

  2. Install the esbuild integration

    Required

    Install the PostHog esbuild plugin and the community Angular custom-esbuild builder:

    Terminal
    npm install --save-dev @posthog/esbuild-plugin @angular-builders/custom-esbuild

    Use the @angular-builders/custom-esbuild major version that matches your Angular major version. For example, use version 20 for Angular 20.

  3. Authenticate the PostHog CLI

    Required

    To authenticate the CLI, call the login command. This opens your browser where you select your organization, project, and API scopes to grant:

    Terminal
    posthog-cli login

    If you are using the CLI in a CI/CD environment such as GitHub Actions, you can set environment variables to authenticate:

    Environment VariableDescriptionSource
    POSTHOG_CLI_HOSTThe PostHog host to connect to [default: https://us.posthog.com]Project settings
    POSTHOG_CLI_PROJECT_IDPostHog project IDProject settings
    POSTHOG_CLI_API_KEYPersonal API key with error tracking write and organization read scopesAPI key settings

    You can also use the --host option instead of the POSTHOG_CLI_HOST environment variable to target a different PostHog instance or region. For EU users:

    Terminal
    posthog-cli --host https://eu.posthog.com [CMD]

  4. Configure the esbuild plugin

    Required

    Create a workspace-local plugin file:

    tools/posthog-esbuild-plugin.ts
    import posthogEsbuildPlugin from '@posthog/esbuild-plugin'
    export default posthogEsbuildPlugin()

    Update your production build target in angular.json:

    angular.json
    "plugins": ["./tools/posthog-esbuild-plugin.ts"],
    "outputHashing": "all",
    "sourceMap": {
    "scripts": true,
    "styles": false,
    "hidden": true,
    "vendor": true
    }
    }
    }
    }
    }

    Keep outputHashing enabled. The plugin uses each content-hashed JavaScript filename as its symbol-set ID.

  5. Build your application

    Required
    Terminal
    ng build --configuration production

    The plugin adds its runtime registration before esbuild computes output hashes. Angular then creates index.html and ngsw.json from the final JavaScript.

  6. Verify the build output

    Checkpoint
    Confirm PostHog metadata is present

    Check a generated JavaScript file in dist/<your-app-name>/browser. It must contain this static marker:

    JavaScript
    /* posthog-chunk-id: output-filename */

    Open the matching .js.map file and confirm its chunk_id equals the JavaScript filename. For example:

    JSON
    {
    "chunk_id": "main-LMD2Y6LY.js"
    }

    You won't see a //# chunkId= comment. The plugin registers the final filename at runtime instead of adding a random ID after the build.

  7. Upload source maps

    Required

    Upload the already-processed output without injecting it again:

    Terminal
    posthog-cli sourcemap upload --directory ./dist/<your-app-name>/browser

    Do not use sourcemap process, sourcemap inject, or sourcemap upload --delete-after after this build. Those commands rewrite JavaScript and invalidate hashes that Angular has already computed.

    If you don't deploy source maps, remove only the .map files after a successful upload:

    Terminal
    find ./dist/<your-app-name>/browser -name '*.map' -delete
  8. Verify source map upload

    Checkpoint
    Confirm source maps are successfully uploaded

Fallback without a custom builder

If you can't replace Angular's standard builder, regenerate the service-worker manifest after PostHog changes the bundles:

Terminal
ng build --configuration production
posthog-cli sourcemap process --directory ./dist/<your-app-name>/browser
npx ngsw-config ./dist/<your-app-name>/browser ./ngsw-config.json /

Run ngsw-config after every command that changes a built asset. This fallback does not repair SRI values or custom CDN manifests. Regenerate those separately after injection.

Still have questions?

Was this page useful?