Skip to content

Switch Heroicons imports to individual direct paths in admin pages, introductions and editor#23285

Merged
leonidasmi merged 26 commits into
trunkfrom
1220-reduce-plugin-zip-size-by-switching-heroicons-imports-to-individual-esm-paths
May 28, 2026
Merged

Switch Heroicons imports to individual direct paths in admin pages, introductions and editor#23285
leonidasmi merged 26 commits into
trunkfrom
1220-reduce-plugin-zip-size-by-switching-heroicons-imports-to-individual-esm-paths

Conversation

@vraja-pro
Copy link
Copy Markdown
Contributor

@vraja-pro vraja-pro commented May 21, 2026

Replaces barrel imports (e.g. import { X } from "@heroicons/react/outline") with individual direct path imports (e.g. import X from "@heroicons/react/outline/X") across admin pages and introductions in packages/js/src/, allowing the bundler to tree-shake unused icons.

Context

  • Waiting for the rest of the PRs for wordpress-seo to be merged to resolve the lint errors.

Summary

This PR can be summarized in the following changelog entry:

  • Switch Heroicons imports to individual direct paths in admin pages and introductions and editor to reduce plugin zip size.

Relevant technical choices:

  • Heroicons v1 exports icons via barrel files (@heroicons/react/outline, @heroicons/react/solid). Webpack cannot fully tree-shake barrel re-exports, so any import from these barrels pulls in every icon in the set — adding significant unused SVG data to the bundle. Individual path imports (e.g. @heroicons/react/outline/ExternalLinkIcon) resolve to separate files, letting Webpack include only the icons actually used.
  • Two no-restricted-imports ESLint rules are added to packages/js/eslint.config.mjs to ban future barrel imports from @heroicons/react/outline and @heroicons/react/solid, preventing regression without manual review.
  • This PR covers packages/js/src/ (admin pages and introductions). The companion PR 1230 switch heroicons individual imports in UI library #23292 (already merged) applied the same pattern to the @yoast/ui-library package.
  • Import paths use the direct file path (@heroicons/react/outline/ExternalLinkIcon) rather than the /esm/ sub-path (@heroicons/react/outline/esm/ExternalLinkIcon). Both achieve tree-shaking; the direct path resolves to the CJS module, which is consistent with Webpack's handling in this project's current build configuration.
  • packages/js/src/introductions/components/modals/google-docs-addon-upsell.js was deleted entirely. The PHP-side should_show() for this introduction has been hardcoded to false, meaning the component is never served to the frontend, making it dead code.

Test instructions

Test instructions for the acceptance test before the PR gets merged

This PR can be acceptance tested by following these steps:

Open the browser console (F12) before starting — verify no JS errors related to icon imports appear at any point.

Academy page (Yoast SEO → Academy)

  • Verify the external-link icon appears on academy course links, the open padlock icon appears on premium course unlock buttons, and the right-arrow icon appears on course navigation links.
Screenshot 2026-05-27 at 15 53 26

Redirects (Yoast SEO → Redirects — requires Premium)

  • In the Redirects menu, verify: code icon, cog icon, switch-horizontal icon (menu items), and closed lock icon (premium feature) all appear.
  • Check the Redirects upsell modal and verify the open padlock icon appears on the upsell button.
  • In the redirects table header, verify the chevron-down icon appears as the sort indicator.
Screenshot 2026-05-27 at 15 50 40

Introductions / announcement modals

Verify each modal shows its icon correctly in one of the Admin pages:

  1. Schema aggregator announcement modal
  • On new site check Schema aggregator announcement modal: right-arrow icon on the learn-more button.
  1. Black Friday announcement modal
    Trigger the black friday promotion by editing src/promotions/domain/black-friday-promotion.php line 16:
new Time_Interval( \gmmktime( 10, 00, 00, 11, 27, 2025 ), \gmmktime( 10, 00, 00, 12, 2, 2025 ) ),
  • Check Black Friday announcement modal: open padlock icon.
  1. AI Brand Insights Free Trial introduction modal:
    For Premium users only. Shows when:
  • User is on a Yoast SEO admin page
  • Yoast SEO Premium is activated
  • User hasn't marked it as seen
  • AI Brand Insights free-trial modal: external-link icon.
  1. Delayed Premium Upsell
    For free users only. Two cases:
  • New install: Shows when now >= first_activated_on + 14 days
  • Returning user (update): Shows when now >= last_updated_on + 14 days
    Both cases also require: user is on a Yoast SEO admin page, hasn't seen another introduction within the last
    week, and hasn't already dismissed this one.
  • Delayed premium upsell modal: external-link icon and checkmark icons on feature list.

Plans page (if accessible)

  • Verify the right-arrow icon appears on call-to-action button links, the external-link icon appears on card links, and the checkmark-circle icon appears in the feature list on AI+ and base plan cards.

Installation success screen (shown after fresh install)

  • Verify the checkmark icon (success indicator), right-arrow icon (navigation links), and external-link icon (external resource links) all render correctly.

Support page (Yoast SEO → Support)

  • Verify the right-arrow icon appears on resource card links.

Black Friday promotion banner (seasonal — test if the banner is currently active)

Trigger the black friday promotion by editing src/promotions/domain/black-friday-promotion.php line 16:

new Time_Interval( \gmmktime( 10, 00, 00, 11, 27, 2025 ), \gmmktime( 10, 00, 00, 12, 2, 2025 ) ),
  • Edit a post and go to the Yoast metabox or sidebar, check the Black Friday promotion banner is visible, verify the X (close) icon, right-arrow icon, all appear correctly.
  • Activate woocommerce and check shopping-cart icon is in the black friday upsell.

Related keyphrase button

  • Edit a post and check in the yoasy editor that the search icon is on the "Discover related keyphrases" buttn (under the focus keyphrase field).

Relevant test scenarios

  • Changes should be tested with the browser console open — verify no JS errors related to icon imports.

Test instructions for QA when the code is in the RC

  • QA should use the same steps as above.

Impact check

This PR affects the following parts of the plugin, which may require extra testing:

  • All pages that render Heroicons: the Yoast SEO sidebar, the metabox, the settings pages, the integrations page, the first-time configuration wizard, and any upsell/modal components.

Other environments

  • This PR also affects Shopify. I have added a changelog entry starting with [shopify-seo], added test instructions for Shopify and attached the Shopify label to this PR.
  • This PR also affects Yoast SEO for Google Docs. I have added a changelog entry starting with [yoast-doc-extension], added test instructions for Yoast SEO for Google Docs and attached the Google Docs Add-on label to this PR.

Documentation

  • I have written documentation for this change. For example, comments in the Relevant technical choices, comments in the code, documentation on Confluence / shared Google Drive / Yoast developer portal, or other.

Quality assurance

  • I have tested this code to the best of my abilities.
  • During testing, I had activated all plugins that Yoast SEO provides integrations for.
  • I have added unit tests to verify the code works as intended.
  • If any part of the code is behind a feature flag, my test instructions also cover cases where the feature flag is switched off.
  • I have written this PR in accordance with my team's definition of done.
  • I have checked that the base branch is correctly set.
  • I have run grunt build:images and committed the results, if my PR introduces or edits images or SVGs.

Innovation

  • No innovation project is applicable for this PR.
  • This PR falls under an innovation project. I have attached the innovation label.
  • I have added my hours to the WBSO document.

Fixes https://github.com/Yoast/reserved-tasks/issues/1234

…le size

Replaces barrel imports (e.g. `import { X } from "@heroicons/react/outline"`)
with direct ESM path imports (e.g. `import X from "@heroicons/react/outline/esm/X"`)
across all ~96 files in packages/js/src/, allowing the bundler to tree-shake unused icons.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vraja-pro vraja-pro added the changelog: non-user-facing Needs to be included in the 'Non-userfacing' category in the changelog label May 21, 2026
…ip-size-by-switching-heroicons-imports-to-individual-esm-paths
@vraja-pro
Copy link
Copy Markdown
Contributor Author

/build-zip

@github-actions
Copy link
Copy Markdown

📦 Plugin zip built successfully!

Download it from the workflow run.

@vraja-pro
Copy link
Copy Markdown
Contributor Author

/build-zip

@github-actions
Copy link
Copy Markdown

📦 Plugin zip built successfully!

Download it from the workflow run.

vraja-pro and others added 2 commits May 21, 2026 15:51
Prevents importing from @heroicons/react/outline and @heroicons/react/solid
barrel paths across all packages that use Heroicons, enforcing individual
ESM path imports instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vraja-pro vraja-pro requested a review from a team as a code owner May 21, 2026 12:57
@vraja-pro
Copy link
Copy Markdown
Contributor Author

/build-zip

@github-actions
Copy link
Copy Markdown

📦 Plugin zip built successfully!

Download it from the workflow run.

@coveralls
Copy link
Copy Markdown

coveralls commented May 21, 2026

Coverage Report for CI Build 0

Coverage at 34.859% (no base build to compare)

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 16813
Covered Lines: 6227
Line Coverage: 37.04%
Relevant Branches: 10566
Covered Branches: 3317
Branch Coverage: 31.39%
Branches in Coverage %: Yes
Coverage Strength: 9.45 hits per line

💛 - Coveralls

vraja-pro and others added 2 commits May 25, 2026 10:05
…ontend

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ata-previews and related-keyphrase-suggestions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vraja-pro vraja-pro force-pushed the 1220-reduce-plugin-zip-size-by-switching-heroicons-imports-to-individual-esm-paths branch from b8b46e5 to 752a560 Compare May 25, 2026 07:07
vraja-pro and others added 12 commits May 25, 2026 10:08
Settings Heroicons import changes extracted to a separate PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…to PR #23295

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ved to PR #23297

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ews files — moved to PR #23298

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ip-size-by-switching-heroicons-imports-to-individual-esm-paths
@vraja-pro vraja-pro changed the title feat: switch Heroicons imports to individual ESm paths to reduce bundle size feat: switch Heroicons imports to individual ESM paths to reduce bundle size May 27, 2026
@vraja-pro vraja-pro changed the title feat: switch Heroicons imports to individual ESM paths to reduce bundle size Switch Heroicons imports to individual ESM paths in admin pages and introductions May 27, 2026
@vraja-pro vraja-pro changed the title Switch Heroicons imports to individual ESM paths in admin pages and introductions Switch Heroicons imports to individual direct paths in admin pages and introductions May 27, 2026
vraja-pro and others added 5 commits May 27, 2026 16:01
…ip-size-by-switching-heroicons-imports-to-individual-esm-paths
…aseButton

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The PHP-side should_show() for this introduction has been hardcoded to
false, so the component is never served to the frontend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vraja-pro vraja-pro changed the title Switch Heroicons imports to individual direct paths in admin pages and introductions Switch Heroicons imports to individual direct paths in admin pages, introductions and editor May 27, 2026
@leonidasmi leonidasmi added this to the 27.9 milestone May 28, 2026
@leonidasmi leonidasmi merged commit 0b40458 into trunk May 28, 2026
40 of 41 checks passed
@leonidasmi leonidasmi deleted the 1220-reduce-plugin-zip-size-by-switching-heroicons-imports-to-individual-esm-paths branch May 28, 2026 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog: non-user-facing Needs to be included in the 'Non-userfacing' category in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants