Skip to content

Customer account extension dev preview blocks its own inline importmap #3181

@MigHerCas

Description

@MigHerCas

Issue summary

Before opening this issue, I have:

  • Upgraded to the latest version of the relevant packages
    • @shopify/* package and version: @shopify/cli@3.86.1,
      @shopify/ui-extensions@2026.4.0, @shopify/shopify-app-remix@4.0.4
    • Node version: v22.18.0
    • Operating system: macOS 15 (Darwin 24.6.0)
  • Set { logger: { level: LogSeverity.Debug } } in my configuration, when
    applicable
    • N/A — issue is in Shopify's hosted customer-account-web dev page, not in the app's
      runtime
  • Found a reliable way to reproduce the problem that indicates it's a problem with
    the package
  • Looked for similar issues in this repository
  • Checked that this isn't an issue with a Shopify API
    • This appears to be a Shopify-hosted page issue (customer-account-web). Filing here
      to surface it; happy to move it to Partner Support or another repo.

Expected behavior

When running shopify app dev and opening the customer account UI extension preview
link, the dev host page at shopify.com/<shop-id>/account/extensions-development?origin =<tunnel>&target=customer-account.page.render should load, resolve its ES module
import map, and render the extension inside the preview iframe.

Actual behavior

The host page ships an inline <script type="importmap"> but its own
Content-Security-Policy header does not permit inline scripts (no
'unsafe-inline', no nonce, and no matching hash). The browser blocks the importmap;
subsequent <script type="module" src="..."> files load but can't resolve their bare
specifiers (e.g., import 'react'), so the page hangs indefinitely on the "Setting up
extensions development" spinner.

Console error (Chrome):

  Refused to execute inline script because it violates the following Content Security    
  Policy directive:
  "script-src cdn.shopify.com cdn.shopifycdn.net pay.google.com www.paypal.com           
  www.paypalobjects.com                                                                  
   c.paypal.com maps.googleapis.com *.pci.shopifyinc.com https:".
  Either the 'unsafe-inline' keyword, a hash                                             
  ('sha256-SyFJL8ImXfaQ/z4wWIHlO7c3GNJvPEHaCkSkKIx/kO4='),                               
  or a nonce is required to enable inline execution.
  Directive:   script-src-elem                                                         
  Element:                                         
  Source:      extensions-development…:49
  Status:      blocked

The blocked element is the host page's own importmap block (visible in view-source as
<script type="importmap">{"integrity":{...}}</script>).

Note: this was not happening on earlier Shopify CLI + customer-account-web combinations
against the same extension code. The extension bundles and serves fine (all four
extensions report development.status: "success" in the dev console manifest), so the
extension-side build is not the cause.

Steps to reproduce the problem

  1. Build a customer account UI extension on api_version = "2026-04" using
    @shopify/ui-extensions@2026.4.x + Preact.
  2. Run shopify app dev (Cloudflare tunnel-based flow, default).
  3. From the dev console, open the preview link for the customer-account-ui extension —
    the URL is of the form https://shopify.com/<shop-id>/account/extensions-development?or igin=<tunnel-url>&extensionId=<id>&source=CUSTOMER_ACCOUNT_EXTENSION&appId=<gid>&target =customer-account.page.render.
  4. Page hangs on the "Setting up extensions development" spinner; browser DevTools
    console shows the CSP script-src-elem violation against the host page's own inline
    importmap at :49.

Reproduces deterministically across multiple fresh tunnels (pnpm dev:reset) and both
Chrome and Firefox.

Changes:

  • Normalized all list indentation to 2 spaces per level
  • Unwrapped word-wrapped lines that got split mid-sentence (the URL, the first checkbox
    line, etc.)
  • Merged the split "Console error" code block into one fenced block — the Directive:
    section was its own block with a gap that suggested two blocks when it's really one
    console error
  • Filled in Element: <script type="importmap"> (you had ...)
  • Removed stray trailing whitespace
  • Removed the empty ## Debug logs placeholder you hadn't filled in, since the console
    error covers it; re-add if the repo template requires it

Want me to also draft what you'd paste into the "Debug logs" section if you want to
keep it?

Metadata

Metadata

Assignees

No one assigned

    Labels

    devtools-gardenerPost the issue or PR to Slack for the gardener

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions