Skip to content

Block editor warning: CSS with .wp-block selector incorrectly added to iframe #46416

@manzoorwanijk

Description

@manzoorwanijk

Reoccurrence of #42689

Image

Impacted plugin

  • Social
  • Jetpack

Quick summary

The block editor shows console warnings like *-css was added to the iframe incorrectly. Please use block.json or enqueue_block_assets to add styles to the iframe. when loading Social/Publicize editor scripts.

This is caused by CSS from the upgrade-nudge component in @automattic/jetpack-shared-extension-utils being bundled into the main stylesheet. The CSS contains a .wp-block selector which triggers the warning.

There are two separate issues causing this CSS to be included:

  1. Direct dependency chain - ai-client imports QuotaExceededMessage which uses the Nudge component
  2. Tree-shaking failure with barrel files - Even if the ai-client usage is removed, the CSS is still bundled due to barrel file re-export evaluation

Steps to reproduce

  1. Open any post in the block editor with the Social enabled
  2. Open the browser developer console
  3. Observe warnings like:
    editor-jetpack-sidebar-css was added to the iframe incorrectly.
    Please use block.json or enqueue_block_assets to add styles to the iframe.
    
    jetpack-external-media-editor-css was added to the iframe incorrectly.
    Please use block.json or enqueue_block_assets to add styles to the iframe.
    

Root cause

The warning is triggered by Gutenberg's iframe component which detects stylesheets containing .wp-block selectors that weren't properly enqueued.

Issue 1: Direct dependency chain through ai-client

The upgrade-nudge CSS is pulled in through this import chain:

Path Import
publicize-components/media-section-v2/index.tsx:6 import { GeneralPurposeImage } from '@automattic/jetpack-ai-client'
ai-client/general-purpose-image.tsx:14 import AiImageModal from './components/ai-image-modal.tsx'
ai-client/ai-image-modal.tsx:15 import QuotaExceededMessage from '../../quota-exceeded-message/index.tsx'
ai-client/quota-exceeded-message/index.tsx:6 import { Nudge as StandardNudge } from '@automattic/jetpack-shared-extension-utils/components'
shared-extension-utils/upgrade-nudge/index.jsx:5 import './style.scss'Side effect

The QuotaExceededMessage component uses the Nudge component, which imports its CSS at the top level as a side effect that always runs when the module is loaded.

Issue 2: Tree-shaking failure with barrel files

Even if the ai-client usage is commented out/removed, the CSS is still bundled due to how barrel file re-exports work.

For example, if we comment out the QuotaExceededMessage import in ai-image-modal.tsx:

// import QuotaExceededMessage from '../../quota-exceeded-message/index.tsx';

The CSS still appears in the bundle because:

  1. publicize-components imports JetpackEditorPanelLogo from @automattic/jetpack-shared-extension-utils/components

  2. The barrel file re-exports multiple components:

    export { default as JetpackEditorPanelLogo } from './jetpack-editor-panel-logo';
    export { Nudge } from './upgrade-nudge'; // Never used, but still evaluated
    export { WpcomSupportLink } from './wpcom-support-link';
  3. When webpack processes this barrel file, it must evaluate all re-export statements to resolve the import. This causes upgrade-nudge/index.jsx to be loaded, triggering the CSS import.

Webpack stats showing the tree-shaking failure

../../js-packages/shared-extension-utils/src/components/upgrade-nudge/index.jsx [built]
  harmony side effect evaluation ./upgrade-nudge .../components/index.js 2:0-40
  [inactive] harmony export imported specifier ./upgrade-nudge  <-- Export is inactive (unused)

The export is marked [inactive] (meaning it's not actually used), but the module is still evaluated due to the harmony side effect evaluation.

Why sideEffects field doesn't fully solve this

Even with "sideEffects": ["*.css", "*.scss"] in package.json, webpack still evaluates the JavaScript modules in the barrel file. The sideEffects field tells webpack that the JS files are side-effect-free for tree-shaking exports, but the CSS import inside upgrade-nudge/index.jsx still runs when the module is evaluated.

Proposed solutions

For Issue 1 (Direct dependency): Lazy load QuotaExceededMessage

Change ai-image-modal.tsx to dynamically import QuotaExceededMessage:

const QuotaExceededMessage = lazy(() => import('../../quota-exceeded-message/index.tsx'));

// In render:
{upgradePromptVisible && (
  <Suspense fallback={null}>
    <QuotaExceededMessage ... />
  </Suspense>
)}

This moves the CSS to a separate chunk that's only loaded when the quota exceeded message is displayed.

For Issue 2 (Tree-shaking): Use direct imports instead of barrel file

Add individual export paths in shared-extension-utils/package.json:

"exports": {
  "./components/jetpack-editor-panel-logo": "./src/components/jetpack-editor-panel-logo/index.jsx",
  "./components/upgrade-nudge": "./src/components/upgrade-nudge/index.jsx",
  "./components/wpcom-support-link": "./src/components/wpcom-support-link/index.jsx"
}

Then update imports in publicize-components:

// Before
import { JetpackEditorPanelLogo } from '@automattic/jetpack-shared-extension-utils/components';

// After
import { JetpackEditorPanelLogo } from '@automattic/jetpack-shared-extension-utils/components/jetpack-editor-panel-logo';

This bypasses the barrel file entirely, so unused components are never evaluated.

Alternative: Decouple Nudge component from wp-block class (Simplest fix)

The wp-block class is only used for alignment styling when context === 'editor-canvas'. This context is only set in one place:

Consumer File Usage
Jetpack paid blocks with-upgrade-banner.jsx:37 const bannerContext = 'editor-canvas' passed to UpgradePlanBanner

All other usages of Nudge (Forms, AI client, etc.) don't pass the context prop.

Replace wp-block with a custom class:

// upgrade-nudge/index.jsx - line 22
const cssClasses = clsx( className, 'jetpack-upgrade-plan-banner', {
	'jetpack-nudge-canvas': context === 'editor-canvas', // Instead of 'wp-block'
	'block-editor-block-list__block': context === 'editor-canvas',
	'jetpack-upgrade-plan__hidden': ! visible,
} );
// style.scss - update selectors
.jetpack-upgrade-plan-banner.jetpack-nudge-canvas[data-align='right']
	.jetpack-upgrade-plan-banner__wrapper,
.jetpack-upgrade-plan-banner.jetpack-nudge-canvas[data-align='left']
	.jetpack-upgrade-plan-banner__wrapper {
	max-width: 580px;
	width: 100%;
}

This removes the .wp-block selector from the CSS entirely, eliminating the Gutenberg warning.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions