Compare commits

..

203 Commits

Author SHA1 Message Date
github-actions[bot] 1e3482a878 chore(release): wxt v0.20.14
📼 VHS / Create VHS (push) Cancelled after 0s
2026-02-06 15:56:04 +00:00
Aaron 734846843f ci: Update templates when bumping WXT version
This closes #2018
2026-02-06 09:51:10 -06:00
Aaron f1eac66494 chore: Fix markdown lint errors 2026-02-06 09:33:06 -06:00
Aaron b4c3280f58 docs: Add new sections to CONTRIBUTING.md
Added sections on WXT's vision, breaking changes policy, and becoming a maintainer.
2026-02-06 09:31:19 -06:00
Invictus Navarchus b2f2998767 chore: update wxt version to ^0.20.13 in all templates (#2019)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2026-02-05 19:36:50 -06:00
blurredart 720eb93c67 docs: add missing import in code sample for configuration (#2057)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2026-02-05 17:31:56 -06:00
dareka cdf8611e0b fix: MaxListenersExceededWarning (#2058) 2026-02-05 17:31:44 -06:00
Scan 905d797b65 docs: Add Margin extension to extensions using wxt (#2060)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2026-02-05 17:22:09 -06:00
tsubasa-ito 6ca8ccc332 docs: add Lofi BGM Player to example projects (#2056)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2026-02-05 17:21:18 -06:00
Nazım Gediz Aydındoğmuş 76496e8865 docs: Added "Teams Chat Exporter" to the homepage (#2050)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2026-02-05 17:20:15 -06:00
Muzammil f38fec8588 docs: Added "Capture It - Capture & Edit Screenshots" to the homepage (#2033)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2026-02-05 17:18:40 -06:00
Ilya Kubariev 4351ac9657 fix: Add .jsonc support for locale files to match docs (#2066) 2026-02-05 17:17:26 -06:00
Mark f3834ac0e2 fix(content-script-context): handle undefined browser.runtime (#2042) 2026-02-05 17:17:16 -06:00
ariasuni 48891a7ca5 fix: rename and make firefoxPrefs in web-ext.config.ts work (#2068) 2026-02-05 17:16:58 -06:00
Aaron 3b6a4aa635 chore: Refresh lockfile and upgrade subdependencies (#2071) 2026-02-05 17:10:47 -06:00
Aaron b20f0471c2 chore: Upgrade major deps (#2070) 2026-02-05 16:57:49 -06:00
Aaron 0f9e66e1e8 chore: Update dependencies (#2069) 2026-02-05 16:37:13 -06:00
Aaron 6fb4cee43f fix: Remove failing test 2026-02-05 16:13:03 -06:00
aklinker1 0e8afbbf56 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2026-02-04 00:37:48 +00:00
aklinker1 83decf7bf5 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2026-01-22 00:35:56 +00:00
aklinker1 5c77cf23b8 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2026-01-21 00:35:03 +00:00
aklinker1 606fd3164c fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2026-01-19 00:36:13 +00:00
aklinker1 71308d0d6f fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2026-01-11 00:37:39 +00:00
Patryk Kuniczak 8bbea7cda4 docs: Fix alignment of 2 last comments of regex patterns (#2012) 2025-12-23 09:42:43 -06:00
Aaron a87d3e4809 chore: Move script-only dev dependencies to top-level package.json (#2007) 2025-12-18 00:28:49 -06:00
Aaron 1f3db58254 chore: Use tsdown to build packages (#2006) 2025-12-18 00:02:19 -06:00
Aaron 43f6c06271 Update out-of-date lockfile 2025-12-17 21:30:07 -06:00
aklinker1 04ae542b13 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-12-17 00:32:12 +00:00
bohuslavsemenov f97c81df0d feat: add onBeforeMount callback to createIframeUi options (#1899)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 17:13:33 -06:00
github-actions[bot] b7b3fc53eb chore(release): wxt v0.20.13
📼 VHS / Create VHS (push) Cancelled after 0s
2025-12-16 23:10:49 +00:00
rxliuli 4b44fb849d fix: Don't return promises from unlisted scripts that do not have an async main function (#1907)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 16:58:46 -06:00
Dan McGee 5d0a266e9c fix: Add another defineItem signature when init function is passed (#1909) 2025-12-16 16:56:24 -06:00
Sebastian Landwehr 24667861db feat: Support .wxtrc config file (#1833)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 16:33:37 -06:00
Johan Kiviniemi 25cc403886 refactor: Use script.text instead of innerHTML in injectScript (#1764)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 16:17:07 -06:00
Johan Kiviniemi 923312c482 feat: Make injectScript return the created script element (#1838)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 16:09:07 -06:00
Johan Kiviniemi adeef6eb73 fix: Make injectScript wait until script is actually loaded (#1763)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 15:54:41 -06:00
Johan Kiviniemi 6f84d45960 feat: Add modifyScript option to injectScript (#1762)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 15:47:40 -06:00
Johan Kiviniemi 938c25cab4 feat: Remove script element immediately in injectScript (#1761)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 15:42:56 -06:00
github-actions[bot] 0404637da8 chore(release): wxt v0.20.12
📼 VHS / Create VHS (push) Cancelled after 0s
2025-12-16 20:57:58 +00:00
Aaron 98d95e4b7f chore(deps): Upgrade node-forge to address CVE-2025-12816, CVE-2025-66031 (#2003) 2025-12-16 14:50:50 -06:00
Aaron 2687a35781 chore(dev-deps): Upgrade happy-dom to address CVE-2025-61927 (#2002) 2025-12-16 14:41:09 -06:00
Aaron 886dae28fa chore: Upgrade dev and non-major prod dependencies (#2000) 2025-12-16 14:33:59 -06:00
Aaron 8c9bc8cdbc chore: Add support for vite-node v5 (#2001) 2025-12-16 11:46:06 -06:00
Jaguar Zhou 5414a0aa34 fix: wxt prepare fails with the error "__vite_ssr_exportName__ is not defined" when using Vite 7 (#1884)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-16 11:04:14 -06:00
K.Utsunomiya 223cf8613b docs: Add note about reviewing project structure in migration guide (#1990) 2025-12-16 08:36:02 -06:00
Alexander Harding 4f1776befc feat: Default to using use_dynamic_url: true for content script css files (#1993)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-15 19:04:07 -06:00
Aaron 38473b9f6c chore: Fix formatting 2025-12-15 18:42:23 -06:00
Manabu Nakazawa 41b428c75f docs: Add "Redirect Web" to homepage (#1995)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-15 18:32:41 -06:00
yiang231 d8d754658f docs: Add "defineConfig" config to startup examples (#1989) 2025-12-15 18:31:43 -06:00
Shawn e52ebf1d53 docs: Change manifest.title to manifest.name in build:manifestGenerated hook example (#1985) 2025-12-15 18:29:10 -06:00
Nguyen Canh Toan 535c7a5f92 docs: add Zen Virtual Piano & Crypto Pulse to example projects (#1977) 2025-12-15 18:27:21 -06:00
TomvdPeet 99b2bd784a Fix comments for includeSources and excludeSources (#1998)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-15 18:19:48 -06:00
Aaron 31ebf966fd chore: Fix other type error after chrome types update 2025-12-15 18:19:25 -06:00
Aaron 6036c6e8e0 chore: Fix type errors after chrome type upgrades 2025-12-15 18:14:29 -06:00
Aaron 597151b5dd ci: Fix browser auto-release workflow 2025-12-15 18:07:44 -06:00
aklinker1 29aeaed223 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-12-11 18:41:00 +00:00
Alex Khrisanfov edf87952c7 ci: Fix update-browser-package action (#1992)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-12-11 12:39:18 -06:00
Aaron 78f8434a06 chore: Use linkedom a test instead of happy-dom (#1957) 2025-10-27 18:11:56 -05:00
Aaron 7eaccad683 chore: Update lockfile 2025-10-27 17:49:24 -05:00
Aaron bfa9c1e1c8 chore: Move PNPM settings to pnpm-workspace.yaml folder 2025-10-27 17:39:59 -05:00
Aaron a2d6577579 docs: Fix syntax error 2025-10-27 17:20:59 -05:00
Ethan Lanting 0e8191488f docs: Added "BetterCampus (prev. BetterCanvas)" to the homepage (#1888)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-10-27 17:08:12 -05:00
Shahil Yadav a1510bb081 docs: Added "Leetcode Fonts" to the homepage (#1889)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-10-27 17:07:05 -05:00
Fantasy 1eaca30f97 docs: Added "sitedata" and "TranslateManga" to homepage (#1902)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-10-27 17:05:52 -05:00
yukidaruma bc79987ed5 docs: Added "Livestream Chat Reader" to the homepage (#1910)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-10-27 17:04:46 -05:00
Alexander Harding 36a501506e feat: Remove data-wxt-* attributes (#1913) 2025-10-27 17:03:01 -05:00
dependabot[bot] e1d47f5f63 chore(deps): bump codecov/codecov-action from 5.5.0 to 5.5.1 (#1920)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-27 16:55:26 -05:00
dependabot[bot] 7faa9b5a64 chore(deps): bump docker/login-action from 3.5.0 to 3.6.0 (#1921)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-27 16:55:00 -05:00
dependabot[bot] 295bee708c chore(deps): bump actions/github-script from 7.0.1 to 8.0.0 (#1922)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-27 16:54:32 -05:00
Burak Unver 9e917481c4 docs: Added "ChatGPT Token Counter" to the homepage (#1926)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-10-27 16:53:41 -05:00
anghunk c5a8b9fb3d docs: Add LinuxDo Scripts extension to the list (#1940) 2025-10-27 16:26:46 -05:00
Florian Kühne 3f4e32f8da fix: Optimize splitShadowRootCss (#1934)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-10-27 16:06:01 -05:00
Aaron f630098f1d chore: Upgrade @aklinker1/check to reduce dev dep size 2025-10-27 09:09:20 -05:00
Eli 608d6e2b54 ci: Don't run cron jobs on forks (#1951) 2025-10-26 20:53:35 -05:00
github-actions[bot] fad5ab6c44 chore(release): @wxt-dev/storage v1.2.6
📼 VHS / Create VHS (push) Cancelled after 0s
2025-10-25 16:40:59 +00:00
Aaron d4cb7997fe ci: Publish packages using OIDC with correctly generated package.json
files
2025-10-25 11:34:59 -05:00
Carlos Ortiz 28364b8be1 ci: publish using pnpm instead of npm (#1943) 2025-10-24 21:11:43 -05:00
github-actions[bot] d28a5c7d5e chore(release): @wxt-dev/storage v1.2.5
📼 VHS / Create VHS (push) Cancelled after 0s
2025-10-13 03:09:36 +00:00
Aaron df707aef4c ci: Use correct version of NPM that supports OIDC auth 2025-10-12 22:02:37 -05:00
Aaron 77af2e58ec ci: Log all NPM versions on runner 2025-10-12 21:59:34 -05:00
Aaron f738e56337 ci: Upgrade actions/setup-node to v5 2025-10-12 21:57:24 -05:00
Aaron f2fe2584e0 ci: try out ubuntu-24.04 runner 2025-10-12 21:53:28 -05:00
Aaron 02673ae017 ci: Debug installed NPM versions more 2025-10-12 21:51:37 -05:00
Aaron 8dd294a163 ci: Disable publishing while debugging NPM changes 2025-10-12 21:49:01 -05:00
Aaron 469e735d53 ci: List installed NPM version 2025-10-12 21:47:57 -05:00
github-actions[bot] b02001796e chore(release): @wxt-dev/storage v1.2.4
📼 VHS / Create VHS (push) Cancelled after 0s
2025-10-13 02:46:42 +00:00
Aaron 0d4d2fdd7e ci: Print NPM version 2025-10-12 21:42:15 -05:00
github-actions[bot] b65e5446fa chore(release): @wxt-dev/storage v1.2.3
📼 VHS / Create VHS (push) Cancelled after 0s
2025-10-13 02:00:40 +00:00
Aaron f75fe3ce5b ci: Separate NPM upgrade from publish step 2025-10-12 20:52:54 -05:00
github-actions[bot] 59ba2712cf chore(release): @wxt-dev/storage v1.2.2
📼 VHS / Create VHS (push) Cancelled after 0s
2025-10-13 01:45:12 +00:00
github-actions[bot] fefe601541 chore(release): @wxt-dev/storage v1.2.1
📼 VHS / Create VHS (push) Cancelled after 0s
2025-10-11 17:41:03 +00:00
Aaron 7291c60413 ci: Support NPM OIDC publishing flow and add provenance (#1932) 2025-10-11 12:36:05 -05:00
Jaguar Zhou bb679102b1 fix: wxt normal logs are drowned by dotenv@17.0.0 ads (#1883) 2025-09-09 08:04:18 -05:00
Alexey Karetnikov 16027c8971 chore(templates): Fix typo vite -> wxt (#1885) 2025-09-09 08:02:40 -05:00
github-actions[bot] 84405a33e3 chore(release): wxt v0.20.11
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-05 13:11:49 +00:00
Aaron bdf795c3f2 chore(deps): Upgrade project subdependencies (#1882) 2025-09-05 08:06:38 -05:00
Qijia Liu ab73084bb5 fix: input_components is supported by mv3 (#1881) 2025-09-05 07:58:09 -05:00
marcellino ornelas e9fb4c5414 fix: Split wxt/testing into separate modules to fix issues with jsdom and happy-dom (#1844)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-09-04 13:56:43 -05:00
github-actions[bot] bc54f525e4 chore(release): @wxt-dev/module-react v1.1.5
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-04 14:06:52 +00:00
Aaron 9170159bc1 chore(deps): Support @vitejs/plugin-react@5 2025-09-04 09:01:01 -05:00
github-actions[bot] fa657a0366 chore(release): wxt v0.20.10
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-04 00:03:50 +00:00
Aaron 24920ddd52 chore(deps): publish-browser-extension upgrade (#1880) 2025-09-03 18:59:39 -05:00
Aaron eb0b372113 chore(deps): Upgrade web-ext-run to support CDP (#1879) 2025-09-03 18:51:26 -05:00
Aaron 8f5f4f674e chore(deps): Upgrade non-breaking production dependencies (#1877) 2025-09-03 18:12:54 -05:00
Aaron 38c1dae9c7 ci: Fix fetch depth for notification workflow 2025-09-03 18:08:35 -05:00
Aaron f92bcd1d14 ci: Remove embed from discord notification 2025-09-03 18:07:10 -05:00
Aaron df09b86d23 ci: Fix notification workflow round 4 2025-09-03 18:05:04 -05:00
Aaron bd5cfa10ad ci: Fix notification workflow round 3 2025-09-03 18:00:57 -05:00
github-actions[bot] 94914dd1ad chore(release): wxt v0.20.9
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-03 22:55:34 +00:00
Aaron dfbb58a2f1 ci: Fix notification workflow round 2 2025-09-03 17:50:13 -05:00
github-actions[bot] 54a1c3576f chore(release): @wxt-dev/storage v1.2.0
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-03 22:49:56 +00:00
Aaron 9ddf73b4fe ci: Fix notification workflow 2025-09-03 17:44:39 -05:00
github-actions[bot] 4ceec1a6ab chore(release): @wxt-dev/runner v0.1.2
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-03 22:44:18 +00:00
Aaron ba314d7434 chore: Add manual dispatch to new notification workflow 2025-09-03 17:39:23 -05:00
github-actions[bot] 55fed67067 chore(release): @wxt-dev/module-vue v1.0.3
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-03 22:39:02 +00:00
Aaron 852390092e ci: Send a weekly notification to discord summarizing the unreleased commits 2025-09-03 17:34:02 -05:00
github-actions[bot] 067be3fed3 chore(release): @wxt-dev/module-svelte v2.0.4
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-03 22:32:01 +00:00
github-actions[bot] 1aecdbb71c chore(release): @wxt-dev/module-solid v1.1.4
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-03 22:26:05 +00:00
github-actions[bot] d8e517cb7b chore(release): @wxt-dev/module-react v1.1.4
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-03 22:17:14 +00:00
github-actions[bot] 9da5b4cacc chore(release): @wxt-dev/analytics v0.5.1
📼 VHS / Create VHS (push) Cancelled after 0s
2025-09-03 22:10:36 +00:00
Aaron 84af32242b ci: Create script to list unreleased commits for each package (#1878) 2025-09-03 17:05:27 -05:00
Aaron 7a81472407 chore(deps): Upgrade all dev dependencies (#1876) 2025-09-03 16:41:00 -05:00
Aaron 9399d8df42 chore: Create script for managing dependency upgrades (#1875) 2025-09-03 16:09:14 -05:00
Aaron 459f73fd5c fix: Add support for @sveltejs/vite-plugin-svelte@6 2025-09-03 10:04:52 -05:00
Aaron c1c3d3b7c5 chore: Upgrade happy-dom to v18.0.1 2025-09-03 09:34:53 -05:00
Aaron 380a9630e5 chore: Upgrade dotenv to v17.2.2 2025-09-03 09:34:09 -05:00
Aaron 984568e00c chore: Upgrade faker to v10 2025-09-03 09:32:07 -05:00
Aaron 5fefd8e083 chore: Upgrade nano-spawn to v1 2025-09-03 09:28:17 -05:00
Aaron a6eef643f6 chore(deps): Upgrade typescript from 5.8.3 to 5.9.2 2025-09-03 09:14:54 -05:00
Aaron a01928e010 chore(deps): Upgrade oxlint from 0.16.8 to 1.14.0 2025-09-03 09:10:47 -05:00
Aaron d901db2316 chore(deps): Upgrade dev dependencies in workspace root (#1874) 2025-09-03 09:05:46 -05:00
Kim Gyeongjae fdda812078 fix: Prevent Unlisted CSS from being excluded in the build when using CSS preprocessor (#1590)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-09-03 08:49:07 -05:00
Atomie CHEN 7c59e9d5b5 fix(types): use TType for DocumentEventMap key in ctx.addEventListener (#1863)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-09-03 08:42:40 -05:00
tanishq-aggarwal c9b0c4da34 feat: Integrate latest measurement protocol changes (#1767)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-09-03 08:22:06 -05:00
TomvdPeet 9f214141b4 docs: Add "Browsely" to homepage (#1850)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-09-03 08:21:39 -05:00
kakuiho 4638e90f02 docs: Added Filmbudd Pro to the homepage (#1853)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-09-03 08:20:27 -05:00
Snow d1c50ab6f8 docs: Add "MultiField CopyCat" to homepage (#1856)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-09-03 08:19:22 -05:00
Abijith Vasanthakumar 489aa0ffd8 docs: Add "ChatSight" to Using WXT section (#1862) 2025-09-03 08:16:54 -05:00
Aaron ebcc605961 chore(deps): Update github actions (#1873) 2025-09-03 08:14:36 -05:00
Aaron bb630049d5 ci: Use node 20 in CI 2025-09-03 07:40:26 -05:00
Aaron 39321adfe1 ci: Use deploy key to bypass branch protection rules (#1861) 2025-08-26 10:48:51 -06:00
aklinker1 ea2b8df906 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-08-15 00:32:30 +00:00
aklinker1 74a9b1aef4 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-08-11 23:42:47 +00:00
github-actions[bot] 8b3e35de94 chore(release): @wxt-dev/auto-icons v1.1.0
📼 VHS / Create VHS (push) Cancelled after 0s
2025-08-11 23:41:58 +00:00
github-actions[bot] 9d4724fa99 chore(release): wxt v0.20.8
📼 VHS / Create VHS (push) Cancelled after 0s
2025-08-11 23:37:18 +00:00
Typed SIGTERM a8379cbd80 docs: Add SVG compatibility note (#1830)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-08-03 09:39:45 -05:00
Sam Carlton bdfb6c5a84 fix(paths): add browser paths for Arc & Dia on macos (#1814)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-08-03 09:24:39 -05:00
sylva 87414d7137 fix: adding missing chromiumPort parameter in web-ext.ts to enable fixed port debugging (#1818)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-08-03 09:16:23 -05:00
Kuba f9d0b64d7a feat: Add overlay option for dev icons (#1825)
Signed-off-by: Kuba Serafinowski <kuba.serafinowski@gmail.com>
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-08-03 09:15:59 -05:00
Aaron 97918710bd docs: Add section on extension API entrypoint limitations (#1743) 2025-08-03 09:14:56 -05:00
btea ac340b3f1e fix: init project should allow the .git folder to exist (#1731)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-08-03 09:14:17 -05:00
Alexander Kachkaev a2097e148b fix: improve Chrome path search (#1823)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-08-03 08:44:06 -05:00
Patryk Kuniczak 190be7f732 fix(rolldown-compat): Only apply footer to content and unlisted scripts via plugin (#1793)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-08-03 08:40:27 -05:00
Aaron 0333ce5c46 chore: Fix type error 2025-08-03 08:02:52 -05:00
Aaron 47df623fd4 docs: Update using WXT section 2025-08-03 07:59:37 -05:00
dependabot[bot] c609efbd9a chore(deps): bump stefanzweifel/git-auto-commit-action from 5 to 6
Bumps [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action) from 5 to 6.
- [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases)
- [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stefanzweifel/git-auto-commit-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: stefanzweifel/git-auto-commit-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 18:26:56 -05:00
Johnny Fekete c8cd41a833 fix: add missing comma in extension IDs (#1827) 2025-07-28 18:02:03 +02:00
Yacine Benslimane 02a0110091 docs: add "Epic Games Library Extension" to docs (#1728)
Co-authored-by: Florian Metz <me@timeraa.dev>
2025-07-24 18:37:07 +02:00
Sam Carlton 6c572c56a3 feat(config): add browser path for Zen via Homebrew (#1813)
Co-authored-by: Florian Metz <me@timeraa.dev>
2025-07-24 18:36:29 +02:00
Greg Zajac 2db516ef3b docs: add 2FAS Pass extension (#1790)
Co-authored-by: Florian Metz <me@timeraa.dev>
2025-07-24 18:33:39 +02:00
Michał Warać 9f3787cd95 docs: add "Piwik PRO Tracking Helper" to the home page (#1822) 2025-07-24 18:05:46 +02:00
Nguyen Canh Toan 5511943237 docs: Update UsingWxtSection.vue (#1740)
Co-authored-by: Florian Metz <me@timeraa.dev>
2025-07-24 18:03:10 +02:00
John Valai 626838eba6 fix: correct typos in docs (#1817) 2025-07-18 03:44:33 -05:00
aklinker1 587328f54c fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-07-17 00:32:55 +00:00
aklinker1 1aa88b1fb6 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-07-16 00:32:35 +00:00
ayu e7db119545 chore: wxt & @wxt-dev/module-vue support Vite 7 (#1771) 2025-07-15 19:21:51 -05:00
Thomas Howlett da79536456 docs: correct content script example code (#1811) 2025-07-15 18:56:58 -05:00
aklinker1 aaaff43731 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-07-12 00:32:04 +00:00
Nishu 5d77142758 docs: adding youtube-video-scheduler in docs. (#1736) 2025-07-12 00:18:36 +02:00
wenyuan 586ea0002b docs: add "Quick Prompt" to the homepage (#1785)
Co-authored-by: Florian Metz <me@timeraa.dev>
2025-07-12 00:18:22 +02:00
流浪大法师 e642d6fe76 docs: add "Add QR Code Generator Icon Back To Address Bar" to the home page (#1800) 2025-07-12 00:15:26 +02:00
Achraf M. Bouhamid 7148f288d5 docs: add "PIPX" to the home page (#1798) 2025-07-12 00:15:14 +02:00
aklinker1 40abf3fb5b fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-07-10 00:31:55 +00:00
aklinker1 adea6c7177 fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-07-09 00:32:25 +00:00
Aaron 96a307e99f docs: Use proper content type when loading extensions on homepage 2025-07-08 02:22:19 -05:00
aklinker1 f0201f72ef fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-07-02 00:31:40 +00:00
aklinker1 0b1b677b3d fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-06-29 00:35:32 +00:00
aklinker1 b1dcec86cd fix: Upgrade @wxt-dev/browser to latest @types/chrome version 2025-06-28 00:30:09 +00:00
Mark 7c783fe565 fix: rootDir, not srdDir for public/_locales (#1751) 2025-06-16 16:56:53 -05:00
요술토끼(wizardrabbit) 9a0207d7cf docs: Added "토탐정" to the homepage (#1750) 2025-06-16 07:51:48 -05:00
Honwhy Wang 1b0e047d6b docs: adding wechat reader enhancer in docs. (#1745) 2025-06-15 18:23:56 -05:00
0xHPZ 7ab3c7e5d9 docs: Added "Chatslator" to the homepage (#1739) 2025-06-14 19:51:04 -05:00
Nishu 9ece49d226 fix: Support negation patterns when including/excluding files from ZIP files (#1517)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-06-14 18:08:04 -05:00
Aaron 1272e2ec74 chore: Fix markdown lint errors and add upgrade @aklinker1/check to
include markdownlint
2025-06-10 16:14:58 -05:00
Aaron db16602018 docs: Add missing breaking change to 0.20 migration (#1636) 2025-06-06 11:03:21 -05:00
Aaron 5c202805b9 fix: Fix bundle variable assignment error with rolldown-vite (#1715) 2025-06-06 10:56:06 -05:00
Aaron bfc8866b69 fix: Fix bad regex from #1707 (#1712) 2025-06-05 01:02:21 -05:00
spookyuser 9aedc29289 docs: Update environment-variables.md with info about env.DEV (#1630)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-06-05 01:01:42 -05:00
Hyunbin Seo e1f3d75ac4 docs: fix svelte app unmount code (#1673) 2025-06-05 00:48:37 -05:00
Aaron 030f23d2e9 docs: Update JSDoc with ways to cancel timeouts and intervals set by content script context 2025-06-05 00:38:57 -05:00
Nishu 6be9a4e71b fix: recreating keyboardShortcuts interface on file changes. (#1465)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2025-06-05 00:35:13 -05:00
Aaron eb0bffb5dd docs: Fix API reference sidebar by naming new module 2025-06-05 00:33:52 -05:00
BrowserLens 240bbb3676 docs: Added "BrowserLens" to the homepage (#1691) 2025-06-05 00:27:14 -05:00
Aaron 7d25110a6e chore: Remove automd 2025-06-05 00:18:43 -05:00
Aaron 598eea703b docs: Simplify README HTML elements 2025-06-04 23:32:24 -05:00
Aaron 8793f7bff4 chore: Manually fix markdownlint errors (#1711) 2025-06-04 18:30:54 -05:00
Aaron c1b3911622 fix: Support http server websocket inside containers (#1707) 2025-06-04 17:40:48 -05:00
Aaron b0bf05109d ci: Use matrix for test jobs (#1708) 2025-06-04 17:40:28 -05:00
Aaron d9cb0ebcc8 chore: Fix auto-fixable markdownlint errors (#1710) 2025-06-04 17:40:00 -05:00
Aaron 1eda21f63f chore: Add markdownlint to repo (#1709) 2025-06-04 17:34:42 -05:00
github-actions[bot] f2dbcde124 chore(release): wxt v0.20.7
📼 VHS / Create VHS (push) Cancelled after 0s
2025-06-02 21:40:42 +00:00
Richard Lee 60f00db2c5 feat: Add DisableLoadExtensionCommandLineSwitch flag to Chromium runner (#1698) 2025-06-02 16:36:24 -05:00
github-actions[bot] a9332453fc chore(release): @wxt-dev/runner v0.1.1
📼 VHS / Create VHS (push) Cancelled after 0s
2025-06-02 20:09:59 +00:00
148 changed files with 10460 additions and 10675 deletions
+3 -5
View File
@@ -4,12 +4,10 @@ description: Install PNPM, Node, and dependencies
inputs:
install:
default: 'true'
type: boolean
description: Whether or not to run 'pnpm install'
installArgs:
default: ''
type: string
description: Additional args to append to "pnpm install"
runs:
@@ -17,12 +15,12 @@ runs:
steps:
- name: 🛠️ Setup PNPM
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f2b2b233b538f500472c7274c7012f57857d8ce0 # v4.1.0
- name: 🛠️ Setup NodeJS
uses: actions/setup-node@v4
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: 18
node-version: 20
cache: pnpm
- name: 📦 Install Dependencies
@@ -0,0 +1,36 @@
name: 🔔 Notify Unreleased Commits
on:
workflow_dispatch:
schedule:
- cron: '0 20 * * 1' # Weekly at 8 PM UTC (3 PM CT)
jobs:
notify:
runs-on: ubuntu-22.04
if: github.repository_owner == 'wxt-dev'
steps:
- name: Checkout
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
with:
fetch-depth: 0
- name: List Commits
id: list-commits
run: |
./scripts/list-unreleased-commits.sh > summary.txt
- name: Discord notification
run: |
PAYLOAD=$(jq -n --arg content "${{ env.MESSAGE }}" '{"content": $content}')
curl -X POST \
-F "payload_json=${PAYLOAD}" \
-F "file1=@summary.txt" \
$DISCORD_WEBHOOK
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_UNRELEASED_COMMITS }}
MESSAGE: |
If a package needs released, please [run the workflow](<https://github.com/wxt-dev/wxt/actions/workflows/release.yml>).
Before running, consider:
- Are there any breaking changes? If so, prepare a list of breaking changes and update the changelog and release notes after the release.
- Are there any PRs open that we wait to release after they're merged?
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
if: ${{ github.repository == 'wxt-dev/wxt' }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Post Thank You Comment
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
comment: Thanks for helping make WXT better!
with:
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
with:
# Only fetch the config file from the repository
sparse-checkout-cone-mode: false
+2 -2
View File
@@ -23,13 +23,13 @@ jobs:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
- name: Login to Docker Registry
uses: docker/login-action@v3
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: https://${{ secrets.DOCKER_REGISTRY_HOSTNAME }}
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
+8 -6
View File
@@ -31,16 +31,18 @@ jobs:
publish:
name: Publish
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
permissions:
contents: write
contents: write # Push version changes
id-token: write # OIDC for NPM publishing
needs:
- validate
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
with:
fetch-depth: 0
ssh-key: ${{ secrets.DEPLOY_KEY }} # https://github.com/sbellone/release-workflow-example
- name: Setup
uses: ./.github/actions/setup
@@ -60,9 +62,9 @@ jobs:
- name: Publish to NPM
working-directory: packages/${{ inputs.package }}
run: |
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" > ~/.npmrc
pnpm build
pnpm publish
pnpm pack
sudo npm i -g npm@latest
/usr/local/bin/npm publish *.tgz
- name: Create GitHub release
run: pnpm tsx scripts/create-github-release.ts ${{ inputs.package }}
+1 -1
View File
@@ -30,7 +30,7 @@ jobs:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
+11 -6
View File
@@ -11,11 +11,15 @@ jobs:
sync:
name: 'Sync with @types/chrome'
runs-on: ubuntu-latest
if: github.repository_owner == 'wxt-dev'
permissions:
contents: write
contents: write # Push version changes
id-token: write # OIDC for NPM publishing
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
with:
ssh-key: ${{ secrets.DEPLOY_KEY }}
- name: Setup
uses: ./.github/actions/setup
@@ -32,15 +36,16 @@ jobs:
- name: Commit Changes
id: commit
uses: stefanzweifel/git-auto-commit-action@v5
uses: stefanzweifel/git-auto-commit-action@01d77ca6cb089da1360e540865f7d035c95aa199 # v6.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
commit_message: 'fix: Upgrade `@wxt-dev/browser` to latest `@types/chrome` version'
- name: Publish Package
- name: Publish to NPM
if: steps.commit.outputs.changes_detected == 'true'
working-directory: packages/browser
run: |
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" > ~/.npmrc
pnpm publish
pnpm pack
sudo npm i -g npm@latest
/usr/local/bin/npm publish *.tgz
+25 -23
View File
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
@@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
@@ -41,7 +41,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
@@ -55,39 +55,41 @@ jobs:
working-directory: packages/wxt-demo
tests:
name: Tests
runs-on: ubuntu-22.04
name: Tests (${{ matrix.title }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- title: 'Linux'
os: ubuntu-22.04
coverage: true
- title: 'Windows'
os: windows-latest
coverage: false
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@22457c87c1b161cf7dde222c3e82b2b5f8d2bed2 # v2.0.2
- name: Run Tests
run: pnpm test:coverage -- --reporter=default --reporter=hanging-process
if: ${{ ! matrix.coverage }}
run: pnpm test
- name: Run Tests (Coverage)
if: matrix.coverage
run: pnpm test:coverage --reporter=default --reporter=hanging-process
- name: Upload Coverage
uses: codecov/codecov-action@v5
if: matrix.coverage
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
windows-tests:
name: Windows Tests
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup
uses: ./.github/actions/setup
- name: Run Tests
run: pnpm test
template:
name: Template
runs-on: ubuntu-22.04
@@ -102,7 +104,7 @@ jobs:
- vue
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
+3 -3
View File
@@ -17,7 +17,7 @@ jobs:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Setup
uses: ./.github/actions/setup
@@ -31,12 +31,12 @@ jobs:
pnpm dlx wxt@latest --version
- name: Record VHS
uses: charmbracelet/vhs-action@v2.1.0
uses: charmbracelet/vhs-action@59641cdc7fadf3978db65eb8c6937ea2752f4ec3 # v2.1.0
with:
path: 'docs/tapes/init-demo.tape'
- name: Save recorded GIF
uses: stefanzweifel/git-auto-commit-action@v5
uses: stefanzweifel/git-auto-commit-action@01d77ca6cb089da1360e540865f7d035c95aa199 # v6.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
+6
View File
@@ -0,0 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/DavidAnson/markdownlint/refs/heads/main/schema/markdownlint-config-schema.json",
"line-length": false,
"no-inline-html": false,
"first-line-heading": false
}
+9
View File
@@ -0,0 +1,9 @@
node_modules
.git
.output
dist
# Generated files
packages/wxt/README.md
packages/*/CHANGELOG.md
docs/api
+4 -4
View File
@@ -60,7 +60,7 @@ representative at an online or offline event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
aaronklinker1@gmail.com.
<aaronklinker1@gmail.com>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
@@ -116,7 +116,7 @@ the community.
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
<https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
@@ -124,5 +124,5 @@ enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
<https://www.contributor-covenant.org/faq>. Translations are available at
<https://www.contributor-covenant.org/translations>.
+42 -6
View File
@@ -6,6 +6,19 @@ If you are changing the docs or fixing a bug, feel free to fork and open a PR.
If you want to add a new feature, please create an issue or discussion first so we can decide if the feature is inline with the vision for WXT.
## WXT's Vision
WXT is two things:
1. A build tool
2. A set of runtime utilities
The long term goal of WXT is provide an opinionated build tool that keeps WXT projects standard, while providing light-weight runtime utils that simplify a lot of the boilerplate/overhead when setting up a new extension.
I also want to provide a way for developers to use either one of those two things independently, and not require them to use both. This is why all of WXT's runtime utils are shipped as their own NPM packages, most of them not bundled inside the core `wxt` package. If you just want to use the packages, they're availalbe, and if you just want to use WXT's built tool, you don't have to import any of WXT's utilities, you can use your own.
> The few runtime utils shipped inside WXT are things that should be used by 90% of extensions. That said, they're also legacy utils left in from before I started creating separate NPM packages, and in the future, they may be removed from the core package.
## Conventional Commits
This project uses [Conventional Commit format](https://www.conventionalcommits.org/en/v1.0.0/) to automatically generate a changelog and better understand the changes in the project
@@ -20,6 +33,19 @@ Here are some examples of conventional commit messages:
The title of your pull request should follow the [conventional commit format](#conventional-commits). When a pull request is merged to the main branch, all changes are going to be squashed into a single commit. The message of this commit will be the title of the pull request. And for every release, the commit messages are used to generate the changelog.
## Breaking Changes Policy
A quick word on WXT's breaking changes policy. I am willing to make breaking changes, but they have to be for a good enough reason - they have to make WXT better as a whole, they can't be based on one opinion.
Breaking changes also require a major release. Major releases have happened once or twice a year, so after you merge your PR, you'll have to wait a little bit before it is released.
To make a breaking change:
1. Make sure you're PR is targeting the `major` branch
2. Add `!` after the conventional commit type (`fix!: ...`, `feat!: ...`, `chore!: ...`, etc) to indicate that it is a breaking change
3. At the top of the PR, provide documentation that will inform developers about the breaking change, why it was done, and how to migrate their extension so nothing breaks.
- This documentation will be put ["Upgrading WXT"](https://wxt.dev/guide/resources/upgrading.html) page in the docs, read through previous breaking change docs for an idea of what is required.
## Setup
WXT uses `pnpm`, so make sure you have it installed.
@@ -146,17 +172,21 @@ Releases are done with GitHub actions:
## Upgrading Dependencies
Use [`taze`](https://www.npmjs.com/package/taze) to upgrade dependencies throughout the entire monorepo.
WXT has custom rules around what dependencies can be upgraded. Use the `scripts/upgrade-deps.ts` script to upgrade dependencies and follow these rules.
```sh
pnpm dlx taze -r
pnpm tsx scripts/upgrade-deps.ts
```
Configuration is in [`taze.config.ts`](./taze.config.ts).
To see all the options, run:
```sh
pnpm tsx scripts/upgrade-deps.ts --help
```
## Install Unreleased Versions
This repo uses https://pkg.pr.new to publish versions of all it's packages for almost every commit. You can install them via:
This repo uses <https://pkg.pr.new> to publish versions of all it's packages for almost every commit. You can install them via:
```sh
npm i https://pkg.pr.new/[package-name]@[ref]
@@ -177,10 +207,16 @@ npm i https://pkg.pr.new/@wxt-dev/module-react@426f907
## Blog Posts
Anyone is welcome to submit a blog post on https://wxt.dev/blog!
Anyone is welcome to submit a blog post on <https://wxt.dev/blog>!
> [!NOTE]
> Before starting on a blog post, please message Aaron on Discord or start a discussion on GitHub to get permission to write about a topic, but most topics are welcome: Major version updates, tutorials, etc.
- **English only**: Blog posts should be written in English. Unfortunately, our maintainers doesn't have the bandwidth right now to translate our docs, let alone blog posts. Sorry 😓
- **English only**: Blog posts should be written in English. Unfortunately, our maintainers don't have the bandwidth right now to translate our docs, let alone blog posts. Sorry 😓
- **AI**: Please only use AI to translate or proof-read your blog post. Don't generate the whole thing... We don't want to publish that.
## Become a Maintainer
If you're interested in becoming a maintainer, send an email to Aaron at <aaronklinker1@gmail.com> with your github username saying you're interested. The process is very informal, I will add you quickly if you've contributed code or answered questions and helped out the community!
Maintainers don't have to just write code - they can manage issues, answer questsions, review PRs, organize and prioritize work - there's lots of ways for you to help out.
+18 -44
View File
@@ -1,50 +1,32 @@
<h1 align="center">
<img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo">
<span>WXT</span>
</h1>
<div align="center">
<p align="center">
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="npm version" src="https://img.shields.io/npm/v/wxt?labelColor=black&color=%234fa048"></a>
<span> </span>
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="downloads" src="https://img.shields.io/npm/dm/wxt?labelColor=black&color=%234fa048"></a>
<span> </span>
<a href="https://github.com/wxt-dev/wxt/blob/main/LICENSE" target="_blank"><img alt="license | MIT" src="https://img.shields.io/npm/l/wxt?labelColor=black&color=%234fa048"></a>
<span> </span>
<a href="https://codecov.io/github/wxt-dev/wxt" target="_blank"><img alt="coverage" src="https://img.shields.io/codecov/c/github/wxt-dev/wxt?labelColor=black&color=%234fa048"></a>
</p>
# <img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo"> WXT
<p align="center">
<span>Next-gen framework for developing web extensions.</span>
<br/>
<span>⚡</span>
<br/>
<q><i>It's like Nuxt, but for Web Extensions</i></q>
</p>
[![npm version](https://img.shields.io/npm/v/wxt?labelColor=black&color=%234fa048)](https://www.npmjs.com/package/wxt)
[![downloads](https://img.shields.io/npm/dm/wxt?labelColor=black&color=%234fa048)](https://www.npmjs.com/package/wxt)
[![license | MIT](https://img.shields.io/npm/l/wxt?labelColor=black&color=%234fa048)](https://github.com/wxt-dev/wxt/blob/main/LICENSE)
[![coverage](https://img.shields.io/codecov/c/github/wxt-dev/wxt?labelColor=black&color=%234fa048)](https://codecov.io/github/wxt-dev/wxt)
<p align="center">
<a href="https://wxt.dev/guide/installation.html" target="_blank">Get Started</a>
&bull;
<a href="https://wxt.dev/api/config.html" target="_blank">Configuration</a>
&bull;
<a href="https://wxt.dev/examples.html" target="_blank">Examples</a>
&bull;
<a href="https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md" target="_blank">Changelog</a>
&bull;
<a href="https://discord.gg/ZFsZqGery9" target="_blank">Discord</a>
</p>
Next-gen framework for developing web extensions.<br/>⚡<br/><q><i>It's like Nuxt, but for Web Extensions</i></q>
[Get Started](https://wxt.dev/guide/installation.html) •
[Configuration](https://wxt.dev/api/config.html) •
[Examples](https://wxt.dev/examples.html) •
[Changelog](https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md) •
[Discord](https://discord.gg/ZFsZqGery9)
</div>
![Example CLI Output](https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/assets/cli-output.png)
## Demo
https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
<https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94>
## Quick Start
Bootstrap a new project:
<!-- automd:pm-x version="latest" name="wxt" args="init" -->
```sh
# npm
npx wxt@latest init
@@ -56,8 +38,6 @@ pnpm dlx wxt@latest init
bunx wxt@latest init
```
<!-- /automd -->
Or see the [installation guide](https://wxt.dev/guide/installation.html) to get started with WXT.
## Features
@@ -79,17 +59,11 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get
WXT is a [MIT-licensed](https://github.com/wxt-dev/wxt/blob/main/LICENSE) open source project with its ongoing development made possible entirely by the support of these awesome backers. If you'd like to join them, please consider [sponsoring WXT's development](https://github.com/sponsors/wxt-dev).
<a href="https://github.com/sponsors/wxt-dev"><img alt="WXT Sponsors" src="https://raw.githubusercontent.com/wxt-dev/static/refs/heads/main/sponsorkit/sponsors.svg"></a>
[![WXT Sponsors](https://raw.githubusercontent.com/wxt-dev/static/refs/heads/main/sponsorkit/sponsors.svg)](https://github.com/sponsors/wxt-dev)
## Contributors
<!-- automd:contributors author="aklinker1" license="MIT" github="wxt-dev/wxt" -->
Published under the [MIT](https://github.com/wxt-dev/wxt/blob/main/LICENSE) license.
Made by [@aklinker1](https://github.com/aklinker1) and [community](https://github.com/wxt-dev/wxt/graphs/contributors) 💛
<br><br>
<a href="https://github.com/wxt-dev/wxt/graphs/contributors">
<img src="https://contrib.rocks/image?repo=wxt-dev/wxt" />
</a>
<!-- /automd -->
[![WXT contributors](https://contrib.rocks/image?repo=wxt-dev/wxt)](https://github.com/wxt-dev/wxt/graphs/contributors)
+32 -1
View File
@@ -4,7 +4,7 @@ import useListExtensionDetails, {
ChromeExtension,
} from '../composables/useListExtensionDetails';
// Add extension IDs here. Order doesn't matter, will be sorted by a combination of weekly active users and rating.
// Add extension IDs to end of the list. On the website, extensions will be sorted by a combination of weekly active users and rating.
// Change the commit message or PR title to: "docs: Added "[extension name]" to the homepage"
const chromeExtensionIds = [
'ocfdgncpifmegplaglcnglhioflaimkd', // GitHub: Better Line Counts
@@ -85,6 +85,37 @@ const chromeExtensionIds = [
'edkhpdceeinkcacjdgebjehipmnbomce', // NZBDonkey - The ultimate NZB file download tool
'cckggnbnimdbbpmdinkkgbbncopbloob', // WeChat Markdown Editor(微信 Markdown 编辑器)
'jcblcjolcojmfopefcighfmkkefbaofg', // Tab Grab
'eehmoikadcijkapfjocnhjclpbaindlb', // BrowserLens - https://browserlens.com/
'hfhellofkjebbchcdffmicekjdomkcmc', // Epic Games Library Extension
'gknigcbhlammoakmmdddkblknanpjiac', // Zen Analytics Pixel Tracker - zapt.web.app
'cnklededohhcbmjjdlbjdkkihkgoggol', // Crypto Pulse - Compose your newtab with nature images, widgets & realtime Crypto Price & Bitcoin RSS.
'miponnamafdenpgjemkknimgjfibicdc', // Youtube Video Scheduler
'nhmbcmalgpkjbomhlhgdicanmkkaajmg', // Chatslator: Livestream Chat Translator
'mbamjfdjbcdgpopfnkkmlohadbbnplhm', // 公众号阅读增强器 - https://wxreader.honwhy.wang
'hannhecbnjnnbbafffmogdlnajpcomek', // 토탐정
'ehboaofjncodknjkngdggmpdinhdoijp', // 2FAS Pass - https://2fas.com/
'hnjamiaoicaepbkhdoknhhcedjdocpkd', // Quick Prompt - https://github.com/wenyuanw/quick-prompt
'kacblhilkacgfnkjfodalohcnllcgmjd', // Add QR Code Generator Icon Back To Address Bar
'fkbdlogfdjmpfepbbbjcgcfbgbcfcnne', // Piwik PRO Tracking Helper
'nkbikckldmljjiiajklecmgmajgapbfl', // PIPX - Take Control of Picture-in-Picture, Automatically
'hgppdobcpkfkmiegekaglonjajeojmdd', // Browsely - AI-powered browser extension
'ehmoihnjgkdimihkhokkmfjdgomohjgm', // Filmbudd Pro - Simple, private and synced ratings and watch notes across all your devices
'alglchohmdikgdjhafiicilegegieafa', // MultiField CopyCat - Copy, Paste & Autofill Web Forms Instantly
'aamihahiiogceidpbnfgehacgiecephe', // ChatSight - Add Table of Contents to ChatGPT
'cndibmoanboadcifjkjbdpjgfedanolh', // BetterCampus (prev. BetterCanvas)
'hinfimgacobnellbncbcpdlpaapcofaa', // Leetcode Fonts - Change fonts in leetcode effortlessly
'kbkbfefhhabpkibojinapkkgciiacggg', // TranslateManga - Manga Translator & Manga Tracker
'emeakbgdecgmdjgegnejpppcnkcnoaen', // SiteData - Free Website Traffic Checker & Reverse AdSense Tool
'gpnckbhgpnjciklpoehkmligeaebigaa', // Livestream Chat Reader - Text-to-Speech for YouTube/Twitch chat
'fjlalaedpfcojcfpkgkglbjjbbkofgnl', // ChatGPT Token Counter - Count tokens in real time on chatgpt conversation
'fbgblmjbeebanackldpbmpacppflgmlj', // LinuxDo Scripts - 为 linux.do 用户提供了一些增强功能
'dfacnjidgbagicaekenjgclfnhdnjjdi', // Zen Virtual Piano - https://zen-piano.web.app/
'naeibcegmgpofimedkmfgjgphfhfhlab', // Crypto Pulse price tracker - https://get-crypto-pulse.web.app/
'ffglckbhfbfmdkefdmjbhpnffkcmlhdh', // Redirect Web - Automatically redirect pages or open them in another app
'eglpfhbhmelampoihamjomgkeobgdofl', // Capture It - Capture & Edit Screenshots
'jmghclbfbbapimhbgnpffbimphlpolnm', // Teams Chat Exporter
'jdcppdokgfbnhiacbeplahgnciahnhck', // Lofi BGM Player - Free lofi focus music for work & study
'cgpmbiiagnehkikhcbnhiagfomajncpa', // Margin - Annotate and highlight any webpage, with your notes saved to the decentralized AT Protocol.
];
const { data, err, isLoading } = useListExtensionDetails(chromeExtensionIds);
@@ -35,6 +35,9 @@ export default function (ids: string[]) {
query,
variables: { ids },
}),
headers: {
'Content-Type': 'application/json',
},
})
.then(async (res) => {
isLoading.value = false;
+20 -11
View File
@@ -8,16 +8,6 @@ outline: deep
During development, WXT uses [`web-ext` by Mozilla](https://www.npmjs.com/package/web-ext) to automatically open a browser window with your extension installed.
:::danger
Chrome 137 removed support for the `--load-extension` CLI flag, which WXT relied on to open the browser with an extension installed. So this feature will not work for Chrome.
You have two options:
1. Install [Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (which still supports the `--load-extension` flag) and [point the `chrome` binary to it](#set-browser-binaries), or
2. [Disable this feature](#disable-opening-browser) and manually load your extension
:::
## Config Files
You can configure browser startup in 3 places:
@@ -42,6 +32,8 @@ You can configure browser startup in 3 places:
To set or customize the browser opened during development:
```ts [web-ext.config.ts]
import { defineWebExtConfig } from 'wxt';
export default defineWebExtConfig({
binaries: {
chrome: '/path/to/chrome-beta', // Use Chrome Beta instead of regular Chrome
@@ -51,6 +43,18 @@ export default defineWebExtConfig({
});
```
```ts [wxt.config.ts]
export default defineConfig({
webExt: {
binaries: {
chrome: '/path/to/chrome-beta', // Use Chrome Beta instead of regular Chrome
firefox: 'firefoxdeveloperedition', // Use Firefox Developer Edition instead of regular Firefox
edge: '/path/to/edge', // Open MS Edge when running "wxt -b edge"
},
},
});
```
By default, WXT will try to automatically discover where Chrome/Firefox are installed. However, if you have chrome installed in a non-standard location, you need to set it manually as shown above.
### Persist Data
@@ -59,11 +63,13 @@ By default, to keep from modifying your browser's existing profiles, `web-ext` c
Right now, Chromium based browsers are the only browsers that support overriding this behavior and persisting data when running the `dev` script multiple times.
To persist data, set the `--user-data-dir` flag:
To persist data, set the `--user-data-dir` flag in any of the config files mentioned above:
:::code-group
```ts [Mac/Linux]
import { defineWebExtConfig } from 'wxt';
export default defineWebExtConfig({
chromiumArgs: ['--user-data-dir=./.wxt/chrome-data'],
});
@@ -71,6 +77,7 @@ export default defineWebExtConfig({
```ts [Windows]
import { resolve } from 'node:path';
import { defineWebExtConfig } from 'wxt';
export default defineWebExtConfig({
// On Windows, the path must be absolute
@@ -92,6 +99,8 @@ You can use any directory you'd like for `--user-data-dir`, the examples above c
If you prefer to load the extension into your browser manually, you can disable the auto-open behavior:
```ts [web-ext.config.ts]
import { defineWebExtConfig } from 'wxt';
export default defineWebExtConfig({
disabled: true,
});
@@ -10,7 +10,7 @@ WXT does several pre-processing steps to try and prevent errors during this proc
2. Use `@webext-core/fake-browser` to create a fake version of the `chrome` and `browser` globals expected by extensions.
3. Pre-process the JS/TS code, stripping out the `main` function then tree-shaking unused code from the file
However, this process is not perfect. It doesn't setup all the globals found in the browser and the APIs may behave differently. As such, **_you should avoid using browser or extension APIs outside the `main` function of your entrypoints!_**
However, this process is not perfect. It doesn't setup all the globals found in the browser and the APIs may behave differently. As such, **_you should avoid using browser or extension APIs outside the `main` function of your entrypoints!_** See [Entrypoint Limitations](/guide/essentials/extension-apis#entrypoint-limitations) for more details.
:::tip
If you're running into errors while importing entrypoints, run `wxt prepare --debug` to see more details about this process. When debugging, WXT will print out the pre-processed code to help you identify issues.
@@ -4,7 +4,7 @@
WXT supports [dotenv files the same way as Vite](https://vite.dev/guide/env-and-mode.html#env-files). Create any of the following files:
```
```plaintext
.env
.env.local
.env.[mode]
@@ -65,7 +65,6 @@ To use environment variables in the manifest, you need to use the function synta
```ts
export default defineConfig({
extensionApi: 'chrome',
modules: ['@wxt-dev/module-vue'],
manifest: { // [!code --]
oauth2: { // [!code --]
@@ -81,3 +80,16 @@ export default defineConfig({
```
WXT can't load your `.env` files until after the config file has been loaded. So by using the function syntax for `manifest`, it defers creating the object until after the `.env` files are loaded into the process.
Note that Vite's runtime environment variables, like `import.meta.env.DEV`, will not be defined. Instead, access the `mode` like this:
```ts
export default defineConfig({
manifest: ({ mode }) => {
const isDev = mode === 'development';
console.log('Is development mode:', isDev);
// ...
},
});
```
+4 -2
View File
@@ -11,7 +11,7 @@ export default defineConfig({
hooks: {
'build:manifestGenerated': (wxt, manifest) => {
if (wxt.config.mode === 'development') {
manifest.title += ' (DEV)';
manifest.name += ' (DEV)';
}
},
},
@@ -32,7 +32,7 @@ Because hooks can be defined in multiple places, including [WXT Modules](/guide/
To see the order for your project, run `wxt prepare --debug` flag and search for the "Hook execution order":
```
```plaintext
⚙ Hook execution order:
⚙ 1. wxt:built-in:unimport
⚙ 2. src/modules/auto-icons.ts
@@ -50,7 +50,9 @@ Changing execution order is simple:
📄 0.my-module.ts
📄 1.another-module.ts
```
- If you need to run an NPM module after user modules, just make it a user module and prefix the filename with a number!
```ts
// modules/2.i18n.ts
export { default } from '@wxt-dev/i18n/module';
+2 -1
View File
@@ -128,7 +128,7 @@ If a version is not present in your `package.json`, it defaults to `"0.0.0"`.
WXT automatically discovers your extension's icon by looking at files in the `public/` directory:
```
```plaintext
public/
├─ icon-16.png
├─ icon-24.png
@@ -235,6 +235,7 @@ If you want to use the `activeTab` permission or the `browser.action.onClicked`
1. Delete the [Popup entrypoint](/guide/essentials/entrypoints#popup) if it exists
2. Add the `action` key to your manifest:
```ts
export default defineConfig({
manifest: {
+1 -1
View File
@@ -20,7 +20,7 @@ export default defineAppConfig({
```
:::warning
This file is committed to the repo, so don't put any secrets here. Instead, use [Environment Variables](#environment-variables)
This file is committed to the repo, so don't put any secrets here. Instead, use [Environment Variables](/guide/essentials/config/environment-variables)
:::
To access runtime config, WXT provides the `useAppConfig` function:
+79 -8
View File
@@ -19,7 +19,7 @@ export default defineContentScript({
This object is responsible for tracking whether or not the content script's context is "invalidated". Most browsers, by default, do not stop content scripts if the extension is uninstalled, updated, or disabled. When this happens, content scripts start reporting this error:
```
```plaintext
Error: Extension context invalidated.
```
@@ -76,6 +76,7 @@ To create a standalone content script that only includes a CSS file:
1. Create the CSS file: `entrypoints/example.content.css`
2. Use the `build:manifestGenerated` hook to add the content script to the manifest:
```ts [wxt.config.ts]
export default defineConfig({
hooks: {
@@ -210,9 +211,7 @@ export default defineContentScript({
anchor: 'body',
onMount: (container) => {
// Create the Svelte app inside the UI container
mount(App, {
target: container,
});
return mount(App, { target: container });
},
onRemove: (app) => {
// Destroy the app when the UI is removed
@@ -395,11 +394,9 @@ export default defineContentScript({
anchor: 'body',
onMount: (container) => {
// Create the Svelte app inside the UI container
mount(App, {
target: container,
});
return mount(App, { target: container });
},
onRemove: () => {
onRemove: (app) => {
// Destroy the app when the UI is removed
unmount(app);
},
@@ -459,6 +456,7 @@ If you don't need to run your UI in the same frame as the content script, you ca
WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/utils/content-script-ui/iframe/functions/createIframeUi), which simplifies setting up the IFrame.
1. Create an HTML page that will be loaded into your IFrame:
```html
<!-- entrypoints/example-iframe.html -->
<!doctype html>
@@ -473,7 +471,9 @@ WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/utils/cont
</body>
</html>
```
1. Add the page to the manifest's `web_accessible_resources`:
```ts [wxt.config.ts]
export default defineConfig({
manifest: {
@@ -486,6 +486,7 @@ WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/utils/cont
},
});
```
1. Create and mount the IFrame:
```ts
@@ -590,6 +591,76 @@ For MV3, `injectScript` is synchronous and the injected script will be evaluated
However for MV2, `injectScript` has to `fetch` the script's text content and create an inline `<script>` block. This means for MV2, your script is injected asynchronously and it will not be evaluated at the same time as your content script's `run_at`.
:::
The `script` element can be modified just before it is added to the DOM by using the `modifyScript` option. This can be used to e.g. modify `script.async`/`script.defer`, add event listeners to the element, or pass data to the script via `script.dataset`. An example:
```ts
// entrypoints/example.content.ts
export default defineContentScript({
matches: ['*://*/*'],
async main() {
await injectScript('/example-main-world.js', {
modifyScript(script) {
script.dataset['greeting'] = 'Hello there';
},
});
},
});
```
```ts
// entrypoints/example-main-world.ts
export default defineUnlistedScript(() => {
console.log(document.currentScript?.dataset['greeting']);
});
```
`injectScript` returns the created script element. It can be used to e.g. send messages to the script in the form of custom events. The script can add an event listener for them via `document.currentScript`. An example of bidirectional communication:
```ts
// entrypoints/example.content.ts
export default defineContentScript({
matches: ['*://*/*'],
async main() {
const { script } = await injectScript('/example-main-world.js', {
modifyScript(script) {
// Add a listener before the injected script is loaded.
script.addEventListener('from-injected-script', (event) => {
if (event instanceof CustomEvent) {
console.log(`${event.type}:`, event.detail);
}
});
},
});
// Send an event after the injected script is loaded.
script.dispatchEvent(
new CustomEvent('from-content-script', {
detail: 'General Kenobi',
}),
);
},
});
```
```ts
// entrypoints/example-main-world.ts
export default defineUnlistedScript(() => {
const script = document.currentScript;
script?.addEventListener('from-content-script', (event) => {
if (event instanceof CustomEvent) {
console.log(`${event.type}:`, event.detail);
}
});
script?.dispatchEvent(
new CustomEvent('from-injected-script', {
detail: 'Hello there',
}),
);
});
```
## Mounting UI to dynamic element
In many cases, you may need to mount a UI to a DOM element that does not exist at the time the web page is initially loaded. To handle this, use the `autoMount` API to automatically mount the UI when the target element appears dynamically and unmount it when the element disappears. In WXT, the `anchor` option is used to target the element, enabling automatic mounting and unmounting based on its appearance and removal.
+8 -8
View File
@@ -300,14 +300,14 @@ When defining content script entrypoints, keep in mind that WXT will import this
<!-- prettier-ignore -->
```ts
browser.runtime.onMessage.addListener((message) => { // [!code --]
// ... // [!code --]
}); // [!code --]
const container = document.createElement('div'); // [!code --]
document.body.append(container); // [!code --]
export default defineBackground(() => {
browser.runtime.onMessage.addListener((message) => { // [!code ++]
// ... // [!code ++]
}); // [!code ++]
export default defineContentScript({
main: function () {
const container = document.createElement('div'); // [!code ++]
document.body.append(container); // [!code ++]
},
});
```
@@ -580,7 +580,7 @@ body {
}
```
Follow Vite's guide to setup your preprocessor of choice: https://vitejs.dev/guide/features.html#css-pre-processors
Follow Vite's guide to setup your preprocessor of choice: <https://vitejs.dev/guide/features.html#css-pre-processors>
CSS entrypoints are always unlisted. To add CSS to a content script, see the [Content Script](/guide/essentials/content-scripts#css) docs.
+1 -1
View File
@@ -1,6 +1,6 @@
# ES Modules
You source code should always be written as ESM. However, you have some control whether an entrypoint is bundled as ESM.
Your source code should always be written as ESM. However, you have some control whether an entrypoint is bundled as ESM.
## HTML Pages <Badge type="warning" text="≥0.0.1" />
+60
View File
@@ -75,3 +75,63 @@ Alternatively, if you're trying to use similar APIs under different names (to su
//
});
```
## Entrypoint Limitations
Because WXT imports your entrypoint files into a NodeJS, non-extension environment, the `chrome`/`browser` variables provided to extensions by the browser **will not be available**.
To prevent some basic errors, WXT polyfills these globals with the same in-memory, fake implementation it uses for testing: [`@webext-core/fake-browser`](https://webext-core.aklinker1.io/fake-browser/installation/). However, not all the APIs have been implemented.
So it is extremely important to NEVER use `browser.*` extension APIs outside the main function of any JS/TS entrypoints (background, content scripts, and unlisted scripts). If you do, you'll see an error like this:
```plaintext
✖ Command failed after 440 ms
ERROR Browser.action.onClicked.addListener not implemented.
```
The fix is simple, just move your API usage into the entrypoint's main function:
:::code-group
```ts [background.ts]
browser.action.onClicked.addListener(() => {
/* ... */
}); // [!code --]
export default defineBackground(() => {
browser.action.onClicked.addListener(() => {
/* ... */
}); // [!code ++]
});
```
```ts [content.ts]
browser.runtime.onMessage.addListener(() => {
/* ... */
}); // [!code --]
export default defineContentScript({
main() {
browser.runtime.onMessage.addListener(() => {
/* ... */
}); // [!code ++]
},
});
```
```ts [unlisted.ts]
browser.runtime.onMessage.addListener(() => {
/* ... */
}); // [!code --]
export default defineUnlistedScript(() => {
browser.runtime.onMessage.addListener(() => {
/* ... */
}); // [!code ++]
});
```
:::
Read [Entrypoint Loaders](/guide/essentials/config/entrypoint-loaders) for more technical details about this limitation.
+5 -1
View File
@@ -9,6 +9,7 @@ This page discusses how to setup internationalization using the vanilla `browser
## Usage
1. Add `default_locale` to your manifest:
```ts
export default defineConfig({
manifest: {
@@ -16,11 +17,12 @@ This page discusses how to setup internationalization using the vanilla `browser
},
});
```
2. Create `messages.json` files in the `public/` directory:
<!-- prettier-ignore -->
```html
📂 {srcDir}/
📂 {rootDir}/
📂 public/
📂 _locales/
📂 en/
@@ -41,9 +43,11 @@ This page discusses how to setup internationalization using the vanilla `browser
```
3. Get the translation:
```ts
browser.i18n.getMessage('helloWorld');
```
4. _Optional_: Add translations for extension name and description:
```json
+2 -2
View File
@@ -72,13 +72,13 @@ jobs:
submit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: 'pnpm'
- name: Install dependencies
@@ -62,6 +62,7 @@ Here are some examples:
```
- HTML file only built for all targets other than `chrome`:
```html
<!doctype html>
<html lang="en">
+3 -3
View File
@@ -9,7 +9,7 @@ WXT provides first class support for Vitest for unit testing:
```ts
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { WxtVitest } from 'wxt/testing';
import { WxtVitest } from 'wxt/testing/vitest-plugin';
export default defineConfig({
plugins: [WxtVitest()],
@@ -36,7 +36,7 @@ This example demonstrates that you don't have to mock `browser.storage` (used by
```ts
import { describe, it, expect } from 'vitest';
import { fakeBrowser } from 'wxt/testing';
import { fakeBrowser } from 'wxt/testing/fake-browser';
const accountStorage = storage.defineItem<Account>('local:account');
@@ -105,4 +105,4 @@ To use a different framework, you will likely have to disable auto-imports, setu
It is possible to do, but will require a bit more setup. Refer to Vitest's setup for an example of how to setup a test environment:
https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/testing/wxt-vitest-plugin.ts
<https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/testing/wxt-vitest-plugin.ts>
+6 -1
View File
@@ -9,18 +9,23 @@ WXT provides a "module system" that let's you run code at different steps in the
There are two ways to add a module to your project:
1. **NPM**: install an NPM package, like [`@wxt-dev/auto-icons`](https://www.npmjs.com/package/@wxt-dev/auto-icons) and add it to your config:
```ts [wxt.config.ts]
export default defineConfig({
modules: ['@wxt-dev/auto-icons'],
});
```
> Searching for ["wxt module"](https://www.npmjs.com/search?q=wxt%20module) on NPM is a good way to find published WXT modules.
2. **Local**: add a file to your project's `modules/` directory:
```
```plaintext
<rootDir>/
modules/
my-module.ts
```
> To learn more about writing your own modules, read the [Writing Modules](/guide/essentials/wxt-modules) docs.
## Module Options
+22
View File
@@ -45,47 +45,63 @@ Once you've run the `dev` command, continue to [Next Steps](#next-steps)!
1. Create a new project
:::code-group
```sh [PNPM]
cd my-project
pnpm init
```
```sh [Bun]
cd my-project
bun init
```
```sh [NPM]
cd my-project
npm init
```
```sh [Yarn]
cd my-project
yarn init
```
:::
2. Install WXT:
:::code-group
```sh [PNPM]
pnpm i -D wxt
```
```sh [Bun]
bun i -D wxt
```
```sh [NPM]
npm i -D wxt
```
```sh [Yarn]
yarn add --dev wxt
```
:::
3. Add an entrypoint, `my-project/entrypoints/background.ts`:
:::code-group
```ts
export default defineBackground(() => {
console.log('Hello world!');
});
```
:::
4. Add scripts to your `package.json`:
```json [package.json]
{
"scripts": {
@@ -99,20 +115,26 @@ Once you've run the `dev` command, continue to [Next Steps](#next-steps)!
}
}
```
5. Run your extension in dev mode
:::code-group
```sh [PNPM]
pnpm dev
```
```sh [Bun]
bun run dev
```
```sh [NPM]
npm run dev
```
```sh [Yarn]
yarn dev
```
:::
WXT will automatically open a browser window with your extension installed.
+1 -1
View File
@@ -1,4 +1,4 @@
# Welcome to WXT!
# Welcome to WXT
WXT is a modern, open-source framework for building web extensions. Inspired by Nuxt, its goals are to:
+9 -10
View File
@@ -20,13 +20,13 @@ await chrome.scripting.getRegisteredContentScripts();
## How do I disable opening the browser automatically during development?
See https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser
See <https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser>
## How do I stay logged into a website during development?
See https://wxt.dev/guide/essentials/config/browser-startup.html#persist-data
See <https://wxt.dev/guide/essentials/config/browser-startup.html#persist-data>
## My component library doesn't work in content scripts!
## My component library doesn't work in content scripts
This is usually caused by one of two things (or both) when using `createShadowRootUi`:
@@ -36,7 +36,6 @@ This is usually caused by one of two things (or both) when using `createShadowRo
Some component libraries manually add CSS to the page by adding a `<style>` or `<link>` element. They place this element in the document's `<head>` by default. This causes your styles to be placed outside the `ShadowRoot` and it's isolation blocks the styles from being applied to your UI.
When a library does this, **you need to tell the library where to put its styles**. Here's the documentation for a few popular component libraries:
- Ant Design: [`StyleProvider`](https://ant.design/docs/react/compatible-style#shadow-dom-usage)
- Mantine: [`MantineProvider#getRootElement` and `MantineProvider#cssVariablesSelector`](https://mantine.dev/theming/mantine-provider/)
@@ -167,11 +166,11 @@ Both issues have the same fix: tell the library to put elements inside the `Shad
## Is there an LLM trained on WXT's docs that I chat with?
Yes! There's a "Ask AI" button in the bottom right of the page, try it out! Or visit https://knowledge.wxt.dev/ for a fullscreen experience.
Yes! There's a "Ask AI" button in the bottom right of the page, try it out! Or visit <https://knowledge.wxt.dev/> for a fullscreen experience.
Additionally, if you want to train your own model or provide context to your editor, you can use the LLM knowledge files hosted by the site:
https://wxt.dev/knowledge/index.json
<https://wxt.dev/knowledge/index.json>
You don't need to crawl the entire website, these files already contain all the relevant docs for training a LLM on WXT. But feel free to crawl it and generate your own files if you want!
@@ -179,11 +178,11 @@ You don't need to crawl the entire website, these files already contain all the
To run the WXT dev server in a devcontainer, but load the dev build of your extension in your browser:
1. **Bind-mount your project directory to your host**
1. **Bind-mount your project directory to your host**
If you're using VS Code, you can open your project folder with the `Dev Containers: Open Folder in Container...` command. This keeps the folder synchronized between your host and the devcontainer, ensuring that the extension `dist` directory remains accessible from the host.
2. **Disable auto-opening the browser**
WXT automatically opens your browser during development, but since you're running inside a container, it won't be able to access it. Follow the instructions [here](https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser) to disable browser auto-opening in your `wxt.config.ts`.
2. **Disable auto-opening the browser**
WXT automatically opens your browser during development, but since you're running inside a container, it won't be able to access it. Follow [the guide here](https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser) to disable browser auto-opening in your `wxt.config.ts`.
3. **Tell WXT to listen on all network interfaces**
3. **Tell WXT to listen on all network interfaces**
To enable hot-reloading, your extension has to connect to the WXT dev server running inside your container. WXT will only listen on `localhost` by default, which prevents connections from outside the devcontainer. To fix this you can instruct WXT to listen on all interfaces with `wxt --host 0.0.0.0`.
+5
View File
@@ -15,6 +15,11 @@ cd path/to/your/project
pnpm dlx wxt@latest init example-wxt --template vanilla
```
:::tip
We recommend reviewing [project structure](/guide/essentials/project-structure.md) before you get started.
You can customize directory names in `wxt.config.ts` to match your project's needs.
:::
In general, you'll need to:
&ensp;<input type="checkbox" /> Install `wxt`<br />
+50 -18
View File
@@ -9,14 +9,18 @@ outline: deep
To upgrade WXT to the latest major version:
1. Install it, skipping scripts so `wxt prepare` doesn't run - it will probably throw an error after a major version change (we'll run it later).
```sh
pnpm i wxt@latest --ignore-scripts
```
2. Follow the upgrade steps below to fix any breaking changes.
3. Run `wxt prepare`. It should succeed and type errors will go away afterwords.
```sh
pnpm wxt prepare
```
4. Manually test to make sure both dev mode and production builds work.
For minor or patch version updates, there are no special steps. Just update it with your package manager:
@@ -44,19 +48,36 @@ Read through all the changes once before updating your code.
WXT's `browser` no longer uses the `webextension-polyfill`!
:::details Why?
See https://github.com/wxt-dev/wxt/issues/784
See <https://github.com/wxt-dev/wxt/issues/784>
:::
To upgrade, you have two options:
1. **Stop using the polyfill** - No changes necessary, though you may want to do some manual testing to make sure everything continues to work. None of the early testers of this feature reported any runtime issues once they stopped using the polyfill.
- If you're already using `extensionApi: "chrome"`, then you don't need to test anything! You're already using the same `browser` object v0.20 provides by default.
1. **Stop using the polyfill**
- If you're already using `extensionApi: "chrome"`, then you're not using the polyfill and there is nothing to change!
- Otherwise there is only one change: `browser.runtime.onMessage` no longer supports using promises to return a response:
```ts
browser.runtime.onMessage.addListener(async () => { // [!code --]
const res = await someAsyncWork(); // [!code --]
return res; // [!code --]
browser.runtime.onMessage.addListener(async (_message, _sender, sendResponse) => { // [!code ++]
someAsyncWork().then((res) => { // [!code ++]
sendResponse(res); // [!code ++]
}); // [!code ++]
return true; // [!code ++]
});
```
2. **Continue using the polyfill** - If you want to keep using the polyfill, you can! One less thing to worry about during this upgrade.
- Install `webextension-polyfill` and WXT's [new polyfill module](https://www.npmjs.com/package/@wxt-dev/webextension-polyfill):
```sh
pnpm i webextension-polyfill @wxt-dev/webextension-polyfill
```
- Add the WXT module to your config:
```ts [wxt.config.ts]
export default defineConfig({
modules: ['@wxt-dev/webextension-polyfill'],
@@ -106,9 +127,9 @@ The default location for the `public/` and `modules/` directories have changed t
- If you follow the default folder structure, you don't need to make any changes.
- If you set a custom `srcDir`, you have two options:
1. Move the your `public/` and `modules/` directories to the project root:
<!-- prettier-ignore -->
```html
1. Move the your `public/` and `modules/` directories to the project root:
<!-- prettier-ignore -->
```html
📂 {rootDir}/
📁 modules/ <!-- [!code ++] -->
📁 public/ <!-- [!code ++] -->
@@ -121,14 +142,16 @@ The default location for the `public/` and `modules/` directories have changed t
📄 app.config.ts
📄 wxt.config.ts
```
2. Keep the folders in the same place and update your project config:
```ts [wxt.config.ts]
export default defineConfig({
srcDir: 'src',
publicDir: 'src/public', // [!code ++]
modulesDir: 'src/modules', // [!code ++]
});
```
2. Keep the folders in the same place and update your project config:
```ts [wxt.config.ts]
export default defineConfig({
srcDir: 'src',
publicDir: 'src/public', // [!code ++]
modulesDir: 'src/modules', // [!code ++]
});
```
### Import Path Changes and `#imports`
@@ -230,6 +253,7 @@ If you've previously loaded the extension into your browser manually for develop
### Deprecated APIs Removed
- `entrypointLoader` option: WXT now uses `vite-node` for importing entrypoints during the build process.
<!-- markdownlint-disable-next-line MD051 -->
> This was deprecated in v0.19.0, see the [v0.19 section](#v0-18-5-rarr-v0-19-0) for migration steps.
- `transformManifest` option: Use the `build:manifestGenerated` hook to transform the manifest instead:
<!-- prettier-ignore -->
@@ -251,6 +275,7 @@ If you've previously loaded the extension into your browser manually for develop
To improve consistency with the `web-ext.config.ts` filename, the "runner" API and config options have been renamed. You can continue using the old names, but they have been deprecated and will be removed in a future version:
1. The `runner` option has been renamed to `webExt`:
```ts [wxt.config.ts]
export default defineConfig({
runner: { // [!code --]
@@ -259,12 +284,16 @@ To improve consistency with the `web-ext.config.ts` filename, the "runner" API a
},
});
```
2. `defineRunnerConfig` has been renamed to `defineWebExtConfig`:
```ts [web-ext.config.ts]
import { defineRunnerConfig } from 'wxt'; // [!code --]
import { defineWebExtConfig } from 'wxt'; // [!code ++]
```
3. The `ExtensionRunnerConfig` type has been renamed to `WebExtConfig`
```ts
import type { ExtensionRunnerConfig } from 'wxt'; // [!code --]
import type { WebExtConfig } from 'wxt'; // [!code ++]
@@ -342,7 +371,7 @@ WXT no longer ships with Common JS support. If you're using CJS, here's your mig
1. Add [`"type": "module"`](https://nodejs.org/api/packages.html#type) to your `package.json`.
2. Change the file extension of any `.js` files that use CJS syntax to `.cjs`, or update them to use EMS syntax.
Vite also provides steps for migrating to ESM. Check them out for more details: https://vitejs.dev/guide/migration#deprecate-cjs-node-api
Vite also provides steps for migrating to ESM. Check them out for more details: <https://vitejs.dev/guide/migration#deprecate-cjs-node-api>
## v0.18.0 &rarr; v0.18.5
@@ -357,11 +386,13 @@ If you already have `<srcDir>/modules` or `<srcDir>/Modules` directory, `wxt pre
You have two options:
1. [Recommended] Keep your files where they are and tell WXT to look in a different folder:
```ts [wxt.config.ts]
export default defineConfig({
modulesDir: 'wxt-modules', // defaults to "modules"
});
```
2. Rename your `modules` directory to something else.
## v0.17.0 &rarr; v0.18.0
@@ -415,7 +446,7 @@ item.watch((newValue: number, oldValue: number) => { // [!code ++]
JS entrypoints in the output directory have been moved. Unless you're doing some kind of post-build work referencing files, you don't have to make any changes.
```
```plaintext
.output/
<target>/
chunks/
@@ -445,7 +476,7 @@ export default defineConfig({
### Renamed Undocumented Constants
Renamed undocumented constants for detecting the build config at runtime in [#380](https://github.com/wxt-dev/wxt/pull/380). Now documented here: https://wxt.dev/guide/multiple-browsers.html#runtime
Renamed undocumented constants for detecting the build config at runtime in [#380](https://github.com/wxt-dev/wxt/pull/380). Now documented here: <https://wxt.dev/guide/multiple-browsers.html#runtime>
- `__BROWSER__` → `import.meta.env.BROWSER`
- `__COMMAND__` → `import.meta.env.COMMAND`
@@ -472,7 +503,7 @@ Renamed undocumented constants for detecting the build config at runtime in [#38
### New `wxt/storage` APIs
`wxt/storage` no longer relies on [`unstorage`](https://www.npmjs.com/package/unstorage). Some `unstorage` APIs, like `prefixStorage`, have been removed, while others, like `snapshot`, are methods on the new `storage` object. Most of the standard usage remains the same. See https://wxt.dev/guide/storage and https://wxt.dev/api/reference/wxt/storage/ for more details ([#300](https://github.com/wxt-dev/wxt/pull/300))
`wxt/storage` no longer relies on [`unstorage`](https://www.npmjs.com/package/unstorage). Some `unstorage` APIs, like `prefixStorage`, have been removed, while others, like `snapshot`, are methods on the new `storage` object. Most of the standard usage remains the same. See <https://wxt.dev/guide/storage> and <https://wxt.dev/api/reference/wxt/storage/> for more details ([#300](https://github.com/wxt-dev/wxt/pull/300))
## v0.11.0 &rarr; v0.12.0
@@ -482,6 +513,7 @@ Renamed undocumented constants for detecting the build config at runtime in [#38
- If you use auto-imports, no changes are required.
- If you have disabled auto-imports, you'll need to manually update your import statements:
```ts
import { defineBackground, defineContentScript } from 'wxt/client'; // [!code --]
import { defineBackground, defineContentScript } from 'wxt/sandbox'; // [!code ++]
+24 -30
View File
@@ -4,7 +4,7 @@
"engines": {
"node": ">=18.20.3"
},
"packageManager": "pnpm@10.10.0",
"packageManager": "pnpm@10.15.1",
"scripts": {
"check": "check && pnpm -r --sequential run check",
"test": "pnpm -r --sequential run test run",
@@ -17,33 +17,38 @@
"docs:preview": "pnpm -s docs:gen && vitepress preview docs"
},
"devDependencies": {
"@aklinker1/buildc": "^1.1.4",
"@aklinker1/check": "2.0.0",
"@commitlint/config-conventional": "^19.8.0",
"@commitlint/types": "^19.8.0",
"@aklinker1/buildc": "^1.1.6",
"@aklinker1/check": "^2.2.0",
"@commitlint/config-conventional": "^20.4.1",
"@commitlint/types": "^20.4.0",
"@types/fs-extra": "^11.0.4",
"@vitest/coverage-v8": "^3.1.2",
"changelogen": "^0.6.1",
"@types/semver": "^7.7.1",
"@vitest/coverage-v8": "^4.0.18",
"changelogen": "^0.6.2",
"consola": "^3.4.2",
"fast-glob": "^3.3.3",
"feed": "^4.2.2",
"fs-extra": "^11.3.0",
"lint-staged": "^15.5.1",
"feed": "^5.2.0",
"fs-extra": "^11.3.3",
"lint-staged": "^16.2.7",
"markdown-it-footnote": "^4.0.0",
"nano-spawn": "^0.2.0",
"prettier": "^3.5.3",
"simple-git-hooks": "^2.13.0",
"tsx": "4.19.4",
"markdownlint-cli": "^0.47.0",
"nano-spawn": "^2.0.0",
"p-map": "^7.0.4",
"prettier": "^3.8.1",
"semver": "^7.7.4",
"simple-git-hooks": "^2.13.1",
"tsdown": "^0.20.3",
"tsx": "4.21.0",
"typedoc": "^0.25.4",
"typedoc-plugin-frontmatter": "^1.3.0",
"typedoc-plugin-frontmatter": "^1.3.1",
"typedoc-plugin-markdown": "4.0.0-next.23",
"typedoc-vitepress-theme": "1.0.0-next.3",
"typescript": "^5.8.3",
"vitepress": "^1.6.3",
"typescript": "^5.9.3",
"vitepress": "^1.6.4",
"vitepress-knowledge": "^0.4.1",
"vitepress-plugin-group-icons": "^1.5.2",
"vitepress-plugin-group-icons": "^1.7.1",
"vitest-mock-extended": "^3.1.0",
"vue": "^3.5.13",
"vue": "^3.5.27",
"wxt": "workspace:*"
},
"simple-git-hooks": {
@@ -51,16 +56,5 @@
},
"lint-staged": {
"*": "prettier --ignore-unknown --write"
},
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": [
"@algolia/client-search",
"search-insights"
]
},
"patchedDependencies": {
"markdown-it-footnote": "patches/markdown-it-footnote.patch"
}
}
}
+29 -1
View File
@@ -1,6 +1,34 @@
# Changelog
## v0.5.1
[compare changes](https://github.com/wxt-dev/wxt/compare/analytics-v0.5.0...analytics-v0.5.1)
### 🚀 Enhancements
- Integrate latest measurement protocol changes ([#1767](https://github.com/wxt-dev/wxt/pull/1767))
### 🩹 Fixes
- Use `@wxt-dev/browser` instead of `@types/chrome` ([#1645](https://github.com/wxt-dev/wxt/pull/1645))
### 🏡 Chore
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
- Change browser workspace dependency to `^` ([c7335add](https://github.com/wxt-dev/wxt/commit/c7335add))
- Fix auto-fixable `markdownlint` errors ([#1710](https://github.com/wxt-dev/wxt/pull/1710))
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Tanishq-aggarwal ([@tanishq-aggarwal](https://github.com/tanishq-aggarwal))
## v0.5.0
[⚠️ breaking changes](https://wxt.dev/guide/resources/upgrading.html) &bull; [compare changes](https://github.com/wxt-dev/wxt/compare/analytics-v0.4.1...analytics-v0.5.0)
### 🩹 Fixes
@@ -9,4 +37,4 @@
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Aaron ([@aklinker1](https://github.com/aklinker1))
+8
View File
@@ -10,15 +10,19 @@ Report analytics events from your web extension extension.
## Install With WXT
1. Install the NPM package:
```bash
pnpm i @wxt-dev/analytics
```
2. In your `wxt.config.ts`, add the WXT module:
```ts
export default defineConfig({
modules: ['@wxt-dev/analytics/module'],
});
```
3. In your `<srcDir>/app.config.ts`, add a provider:
```ts
@@ -49,9 +53,11 @@ Report analytics events from your web extension extension.
## Install Without WXT
1. Install the NPM package:
```bash
pnpm i @wxt-dev/analytics
```
2. Create an `analytics` instance:
```ts
@@ -66,10 +72,12 @@ Report analytics events from your web extension extension.
```
3. Import your analytics module in the background to initialize the message listener:
```ts
// background.ts
import './utils/analytics';
```
4. Then use your `analytics` instance to report events:
```ts
-21
View File
@@ -1,21 +0,0 @@
import { defineBuildConfig } from 'unbuild';
import { resolve } from 'node:path';
// Build module and plugins
export default defineBuildConfig({
rootDir: resolve(__dirname, 'modules/analytics'),
outDir: resolve(__dirname, 'dist'),
entries: [
{ input: 'index.ts', name: 'module' },
{ input: 'client.ts', name: 'index' },
'background-plugin.ts',
'types.ts',
'providers/google-analytics-4.ts',
'providers/umami.ts',
],
externals: ['#analytics'],
replace: {
'import.meta.env.NPM': 'true',
},
declaration: true,
});
@@ -253,7 +253,8 @@ function defineStorageItem<T>(
): AnalyticsStorageItem<T> {
return {
getValue: async () =>
(await browser.storage.local.get(key))[key] ?? defaultValue,
(await browser.storage.local.get<Record<string, any>>(key))[key] ??
defaultValue,
setValue: (newValue) => browser.storage.local.set({ [key]: newValue }),
};
}
@@ -22,10 +22,10 @@ export default defineWxtModule({
// Paths
const wxtAnalyticsFolder = resolve(wxt.config.wxtDir, 'analytics');
const wxtAnalyticsIndex = resolve(wxtAnalyticsFolder, 'index.ts');
const clientModuleId = import.meta.env.NPM
const clientModuleId = process.env.NPM
? '@wxt-dev/analytics'
: resolve(wxt.config.modulesDir, 'analytics/client');
const pluginModuleId = import.meta.env.NPM
const pluginModuleId = process.env.NPM
? '@wxt-dev/analytics/background-plugin'
: resolve(wxt.config.modulesDir, 'analytics/background-plugin');
@@ -40,7 +40,7 @@ export default defineWxtModule({
// Generate #analytics module
const wxtAnalyticsCode = [
`import { createAnalytics } from '${
import.meta.env.NPM
process.env.NPM
? clientModuleId
: relative(wxtAnalyticsFolder, clientModuleId)
}';`,
@@ -46,6 +46,7 @@ export const googleAnalytics4 =
ad_personalization: 'DENIED',
},
user_properties: mappedUserProperties,
user_agent: navigator.userAgent,
events: [
{
name: eventName,
+5 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@wxt-dev/analytics",
"version": "0.5.0",
"version": "0.5.1",
"description": "Add analytics to your web extension",
"repository": {
"type": "git",
@@ -35,7 +35,7 @@
}
},
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"files": [
"dist"
],
@@ -43,7 +43,7 @@
"dev": "buildc --deps-only -- wxt",
"dev:build": "buildc --deps-only -- wxt build",
"check": "pnpm build && check",
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"prepack": "pnpm -s build",
"prepare": "buildc --deps-only -- wxt prepare"
},
@@ -51,11 +51,9 @@
"wxt": ">=0.20.0"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@types/ua-parser-js": "^0.7.39",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"wxt": "workspace:*"
},
"dependencies": {
+17
View File
@@ -0,0 +1,17 @@
import { defineConfig } from 'tsdown';
export default defineConfig({
entry: {
index: './modules/analytics/client.ts',
module: './modules/analytics/index.ts',
'background-plugin': './modules/analytics/background-plugin.ts',
types: './modules/analytics/types.ts',
'providers/google-analytics-4':
'./modules/analytics/providers/google-analytics-4.ts',
'providers/umami': './modules/analytics/providers/umami.ts',
},
external: ['#analytics'],
define: {
'process.env.NPM': 'true',
},
});
+32
View File
@@ -1,5 +1,37 @@
# Changelog
## v1.1.0
[compare changes](https://github.com/wxt-dev/wxt/compare/auto-icons-v1.0.2...auto-icons-v1.1.0)
### 🚀 Enhancements
- Add overlay option for dev icons ([#1825](https://github.com/wxt-dev/wxt/pull/1825))
### 📖 Documentation
- Rewrite and restructure the documentation website ([#933](https://github.com/wxt-dev/wxt/pull/933))
- Use full URLs in README so they work on the docs site ([d20793d5](https://github.com/wxt-dev/wxt/commit/d20793d5))
- Add SVG compatibility note ([#1830](https://github.com/wxt-dev/wxt/pull/1830))
### 🏡 Chore
- Add `oxlint` for linting ([#947](https://github.com/wxt-dev/wxt/pull/947))
- **deps:** Bump sharp from 0.33.4 to 0.33.5 ([#959](https://github.com/wxt-dev/wxt/pull/959))
- Upgrade all non-major dependencies ([#1040](https://github.com/wxt-dev/wxt/pull/1040))
- **deps:** Upgrade all non-major dependencies ([#1164](https://github.com/wxt-dev/wxt/pull/1164))
- **deps:** Bump dev and non-breaking major dependencies ([#1167](https://github.com/wxt-dev/wxt/pull/1167))
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
### ❤️ Contributors
- Typed SIGTERM ([@typed-sigterm](https://github.com/typed-sigterm))
- Kuba ([@zizzfizzix](https://github.com/zizzfizzix))
- Aaron ([@aklinker1](https://github.com/aklinker1))
## v1.0.2
[compare changes](https://github.com/wxt-dev/wxt/compare/auto-icons-v1.0.1...auto-icons-v1.0.2)
+2 -1
View File
@@ -5,7 +5,8 @@
## Features
- Generate extension icons with the correct sizes
- Make the icon greyscale during development
- Make the icon greyscale or include a visible overlay during development
- SVG is supported
## Usage
+8 -10
View File
@@ -24,10 +24,10 @@
}
],
"license": "MIT",
"version": "1.0.2",
"version": "1.1.0",
"type": "module",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"types": "./dist/index.d.mts",
@@ -38,7 +38,7 @@
"dist"
],
"scripts": {
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"check": "pnpm build && check"
},
"peerDependencies": {
@@ -46,15 +46,13 @@
},
"dependencies": {
"defu": "^6.1.4",
"fs-extra": "^11.3.0",
"sharp": "^0.34.1"
"fs-extra": "^11.3.3",
"sharp": "^0.34.5"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"oxlint": "^0.16.8",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"oxlint": "^1.43.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"wxt": "workspace:*"
}
}
+59 -12
View File
@@ -14,11 +14,24 @@ export default defineWxtModule<AutoIconsOptions>({
{
enabled: true,
baseIconPath: resolve(wxt.config.srcDir, 'assets/icon.png'),
grayscaleOnDevelopment: true,
developmentIndicator: 'grayscale',
sizes: [128, 48, 32, 16],
},
);
// Backward compatibility for the deprecated option
if (options?.grayscaleOnDevelopment !== undefined) {
wxt.logger.warn(
'`[auto-icons]` "grayscaleOnDevelopment" is deprecated. Use "developmentIndicator" instead.',
);
if (options?.developmentIndicator === undefined) {
parsedOptions.developmentIndicator = options!.grayscaleOnDevelopment
? 'grayscale'
: false;
}
}
const resolvedPath = resolve(wxt.config.srcDir, parsedOptions.baseIconPath);
if (!parsedOptions.enabled)
@@ -42,21 +55,44 @@ export default defineWxtModule<AutoIconsOptions>({
});
wxt.hooks.hook('build:done', async (wxt, output) => {
const image = sharp(resolvedPath).png();
if (
wxt.config.mode === 'development' &&
parsedOptions.grayscaleOnDevelopment
) {
image.grayscale();
}
const outputFolder = wxt.config.outDir;
for (const size of parsedOptions.sizes) {
const resized = image.resize(size);
const resizedImage = sharp(resolvedPath).resize(size).png();
if (wxt.config.mode === 'development') {
if (parsedOptions.developmentIndicator === 'grayscale') {
resizedImage.grayscale();
} else if (parsedOptions.developmentIndicator === 'overlay') {
// Helper to build an overlay that places a yellow rectangle at the bottom
// of the icon with the text "DEV" in black. The overlay has the same
// dimensions as the icon so we can composite it with default gravity.
const buildDevOverlay = (size: number) => {
const rectHeight = Math.round(size * 0.5);
const fontSize = Math.round(size * 0.35);
return Buffer.from(`<?xml version="1.0" encoding="UTF-8"?>
<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="${size - rectHeight}" width="${size}" height="${rectHeight}" fill="#ffff00" />
<text x="${size / 2}" y="${size - rectHeight / 2}" font-family="Arial, Helvetica, sans-serif" font-size="${fontSize}" font-weight="bold" fill="black" text-anchor="middle" dominant-baseline="middle">DEV</text>
</svg>`);
};
const overlayBuffer = await sharp(buildDevOverlay(size))
.png()
.toBuffer();
resizedImage.composite([
{
input: overlayBuffer,
left: 0,
top: 0,
},
]);
}
}
ensureDir(resolve(outputFolder, 'icons'));
await resized.toFile(resolve(outputFolder, `icons/${size}.png`));
await resizedImage.toFile(resolve(outputFolder, `icons/${size}.png`));
output.publicAssets.push({
type: 'asset',
@@ -89,9 +125,20 @@ export interface AutoIconsOptions {
* @default "<srcDir>/assets/icon.png"
*/
baseIconPath?: string;
/**
* Apply a visual indicator to the icon when running in development mode.
*
* "grayscale" converts the icon to grayscale.
* "overlay" covers the bottom half with a yellow rectangle and writes "DEV" in black text.
* Set to `false` to disable any indicator.
*
* @default "grayscale"
*/
developmentIndicator?: 'grayscale' | 'overlay' | false;
/**
* Grayscale the image when in development mode to indicate development
* @default true
* @deprecated Use `developmentIndicator` instead
*/
grayscaleOnDevelopment?: boolean;
/**
+6 -7
View File
@@ -1,7 +1,7 @@
{
"name": "@wxt-dev/browser",
"description": "Provides a cross-browser API for using extension APIs and types based on @types/chrome",
"version": "0.0.326",
"version": "0.1.36",
"type": "module",
"main": "src/index.mjs",
"types": "src/index.d.ts",
@@ -23,12 +23,11 @@
"src"
],
"devDependencies": {
"@types/chrome": "0.0.326",
"fs-extra": "^11.3.0",
"nano-spawn": "^0.2.0",
"tsx": "4.19.4",
"typescript": "^5.8.3",
"vitest": "^3.1.2"
"@types/chrome": "0.1.36",
"fs-extra": "^11.3.3",
"nano-spawn": "^2.0.0",
"typescript": "^5.9.3",
"vitest": "^4.0.18"
},
"dependencies": {
"@types/filesystem": "*",
+1 -3
View File
@@ -60,9 +60,7 @@ for (const { file, srcPath, destPath } of declarationFileMapping) {
// Done!
console.log(
'\x1b[32m✔\x1b[0m Done in ' + performance.now().toFixed(0) + ' ms',
);
console.log('\x1b[32m✔\x1b[0m Done in ' + performance.now().toFixed(0) + ' ms');
// Transformations
+4443 -5051
View File
File diff suppressed because it is too large Load Diff
+4 -5
View File
@@ -24,10 +24,9 @@
],
"devDependencies": {
"@types/chrome": "{{chromeTypesVersion}}",
"fs-extra": "^11.3.0",
"nano-spawn": "^0.2.0",
"tsx": "4.19.4",
"typescript": "^5.8.3",
"vitest": "^3.1.2"
"fs-extra": "^11.3.3",
"nano-spawn": "^2.0.0",
"typescript": "^5.9.3",
"vitest": "^4.0.18"
}
}
+2 -2
View File
@@ -6,7 +6,7 @@
1. Simple messages file format
2. Plural form support
3. Integrates with the [I18n Ally VS Code extension](#vscode)
3. Integrates with the [I18n Ally VS Code extension](#vs-code)
It also provides several benefits over other non-web extension specific i18n packages:
@@ -81,7 +81,7 @@ And you're done! Using WXT, you get type-safety out of the box.
> [!NOTE]
> For the best DX, you should to integrate `@wxt-dev/i18n` into your build process. This enables:
>
> 1. Plural forms
> 2. Simple messages file format
> 3. Type safety
+8 -10
View File
@@ -21,13 +21,13 @@
"license": "MIT",
"funding": "https://github.com/sponsors/wxt-dev",
"scripts": {
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"check": "buildc --deps-only -- check",
"test": "buildc --deps-only -- vitest"
},
"dependencies": {
"@wxt-dev/browser": "workspace:^",
"chokidar": "^4.0.3",
"chokidar": "^5.0.0",
"confbox": "^0.1.8 || ^0.2.2",
"fast-glob": "^3.3.3"
},
@@ -40,19 +40,17 @@
}
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@types/node": "^20.17.6",
"oxlint": "^0.16.8",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"vitest": "^3.1.2",
"vitest-plugin-random-seed": "^1.1.1",
"oxlint": "^1.43.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"vitest": "^4.0.18",
"vitest-plugin-random-seed": "^1.1.2",
"wxt": "workspace:*"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"import": {
+2 -2
View File
@@ -44,7 +44,7 @@ export default defineWxtModule<I18nOptions>({
options ?? {};
const getLocalizationFiles = async () => {
const files = await glob('*.{json,json5,yml,yaml,toml}', {
const files = await glob('*.{json,json5,jsonc,yml,yaml,toml}', {
cwd: localesDir,
absolute: true,
});
@@ -88,7 +88,7 @@ export default defineWxtModule<I18nOptions>({
)!;
if (defaultLocaleFile == null) {
throw Error(
`\`[i18n]\` Required localization file does not exist: \`<localesDir>/${wxt.config.manifest.default_locale}.{json|json5|yml|yaml|toml}\``,
`\`[i18n]\` Required localization file does not exist: \`<localesDir>/${wxt.config.manifest.default_locale}.{json|json5|jsonc|yml|yaml|toml}\``,
);
}
+13
View File
@@ -0,0 +1,13 @@
import { defineConfig } from 'tsdown';
const entry = ['src/index.ts', 'src/build.ts', 'src/module.ts'];
export default defineConfig([
{
entry,
},
{
entry,
format: 'cjs',
},
]);
+38
View File
@@ -1,5 +1,43 @@
# Changelog
## v1.1.5
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.1.4...module-react-v1.1.5)
### 🏡 Chore
- **deps:** Support @vitejs/plugin-react@5 ([9170159b](https://github.com/wxt-dev/wxt/commit/9170159b))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
## v1.1.4
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.1.3...module-react-v1.1.4)
### 🩹 Fixes
- Add support for WXT v0.20.0 ([c9dca022](https://github.com/wxt-dev/wxt/commit/c9dca022))
### 🏡 Chore
- Add funding links to `package.json` files ([#1446](https://github.com/wxt-dev/wxt/pull/1446))
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
- **deps:** Upgrade to Vite 6 and related dependencies ([#1496](https://github.com/wxt-dev/wxt/pull/1496))
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
- **deps:** Update all dependencies ([#1648](https://github.com/wxt-dev/wxt/pull/1648))
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Okinea Dev <hi@okinea.dev>
## v1.1.3
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.1.2...module-react-v1.1.3)
-12
View File
@@ -1,12 +0,0 @@
import { defineBuildConfig } from 'unbuild';
import { resolve } from 'node:path';
export default defineBuildConfig({
rootDir: resolve(__dirname, 'modules'),
outDir: resolve(__dirname, 'dist'),
entries: [{ input: 'react.ts', name: 'index' }],
rollup: {
emitCJS: true,
},
declaration: true,
});
+10 -12
View File
@@ -18,11 +18,11 @@
},
"license": "MIT",
"funding": "https://github.com/sponsors/wxt-dev",
"version": "1.1.3",
"version": "1.1.5",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"import": {
@@ -41,24 +41,22 @@
"scripts": {
"dev": "wxt",
"check": "pnpm build && check",
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"prepare": "buildc --deps-only -- wxt prepare"
},
"peerDependencies": {
"wxt": ">=0.19.16"
},
"dependencies": {
"@vitejs/plugin-react": "^4.4.1"
"@vitejs/plugin-react": "^4.4.1 || ^5.0.0"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.3",
"publint": "^0.3.12",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"publint": "^0.3.17",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"typescript": "^5.9.3",
"wxt": "workspace:*"
}
}
+15
View File
@@ -0,0 +1,15 @@
import { defineConfig } from 'tsdown';
const entry = {
index: './modules/react.ts',
};
export default defineConfig([
{
entry,
},
{
entry,
format: 'cjs',
},
]);
+28
View File
@@ -1,5 +1,33 @@
# Changelog
## v1.1.4
[compare changes](https://github.com/wxt-dev/wxt/compare/module-solid-v1.1.3...module-solid-v1.1.4)
### 🩹 Fixes
- Add support for WXT v0.20.0 ([c9dca022](https://github.com/wxt-dev/wxt/commit/c9dca022))
### 🏡 Chore
- **deps-dev:** Bump solid-js from 1.9.3 to 1.9.4 ([#1391](https://github.com/wxt-dev/wxt/pull/1391))
- Add funding links to `package.json` files ([#1446](https://github.com/wxt-dev/wxt/pull/1446))
- **deps:** Bump vite-plugin-solid from 2.10.2 to 2.11.6 ([#1491](https://github.com/wxt-dev/wxt/pull/1491))
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
- **deps:** Upgrade to Vite 6 and related dependencies ([#1496](https://github.com/wxt-dev/wxt/pull/1496))
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
- **deps:** Update all dependencies ([#1648](https://github.com/wxt-dev/wxt/pull/1648))
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Okinea Dev <hi@okinea.dev>
## v1.1.3
[compare changes](https://github.com/wxt-dev/wxt/compare/module-solid-v1.1.2...module-solid-v1.1.3)
-12
View File
@@ -1,12 +0,0 @@
import { defineBuildConfig } from 'unbuild';
import { resolve } from 'node:path';
export default defineBuildConfig({
rootDir: resolve(__dirname, 'modules'),
outDir: resolve(__dirname, 'dist'),
entries: [{ input: 'solid.ts', name: 'index' }],
rollup: {
emitCJS: true,
},
declaration: true,
});
+7 -9
View File
@@ -18,11 +18,11 @@
},
"license": "MIT",
"funding": "https://github.com/sponsors/wxt-dev",
"version": "1.1.3",
"version": "1.1.4",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"import": {
@@ -41,21 +41,19 @@
"scripts": {
"dev": "wxt",
"check": "pnpm build && check",
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"prepare": "buildc --deps-only -- wxt prepare"
},
"peerDependencies": {
"wxt": ">=0.19.16"
},
"dependencies": {
"vite-plugin-solid": "^2.11.6"
"vite-plugin-solid": "^2.11.10"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"publint": "^0.3.12",
"solid-js": "^1.9.6",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"publint": "^0.3.17",
"solid-js": "^1.9.11",
"typescript": "^5.9.3",
"wxt": "workspace:*"
}
}
+15
View File
@@ -0,0 +1,15 @@
import { defineConfig } from 'tsdown';
const entry = {
index: './modules/solid.ts',
};
export default defineConfig([
{
entry,
},
{
entry,
format: 'cjs',
},
]);
+24
View File
@@ -1,5 +1,29 @@
# Changelog
## v2.0.4
[compare changes](https://github.com/wxt-dev/wxt/compare/module-svelte-v2.0.3...module-svelte-v2.0.4)
### 🩹 Fixes
- Add support for @sveltejs/vite-plugin-svelte@6 ([459f73fd](https://github.com/wxt-dev/wxt/commit/459f73fd))
### 🏡 Chore
- Add funding links to `package.json` files ([#1446](https://github.com/wxt-dev/wxt/pull/1446))
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Okinea Dev <hi@okinea.dev>
## v2.0.3
[compare changes](https://github.com/wxt-dev/wxt/compare/module-svelte-v2.0.2...module-svelte-v2.0.3)
+6 -8
View File
@@ -18,11 +18,11 @@
},
"license": "MIT",
"funding": "https://github.com/sponsors/wxt-dev",
"version": "2.0.3",
"version": "2.0.4",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"import": {
@@ -39,7 +39,7 @@
"dist"
],
"scripts": {
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"check": "pnpm build && check"
},
"peerDependencies": {
@@ -47,13 +47,11 @@
"svelte": ">=5"
},
"dependencies": {
"@sveltejs/vite-plugin-svelte": "^4.0.0 || ^5.0.0"
"@sveltejs/vite-plugin-svelte": "^4.0.0 || ^5.0.0 || ^6.0.0"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"wxt": "workspace:*"
}
}
+15
View File
@@ -0,0 +1,15 @@
import { defineConfig } from 'tsdown';
const entry = {
index: './src/index.ts',
};
export default defineConfig([
{
entry,
},
{
entry,
format: 'cjs',
},
]);
+22
View File
@@ -1,5 +1,27 @@
# Changelog
## v1.0.3
[compare changes](https://github.com/wxt-dev/wxt/compare/module-vue-v1.0.2...module-vue-v1.0.3)
### 🏡 Chore
- Add funding links to `package.json` files ([#1446](https://github.com/wxt-dev/wxt/pull/1446))
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
- Wxt & @wxt-dev/module-vue support Vite 7 ([#1771](https://github.com/wxt-dev/wxt/pull/1771))
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Ayu ([@ayu-exorcist](https://github.com/ayu-exorcist))
- Okinea Dev <hi@okinea.dev>
## v1.0.2
[compare changes](https://github.com/wxt-dev/wxt/compare/module-vue-v1.0.1...module-vue-v1.0.2)
+6 -8
View File
@@ -18,11 +18,11 @@
},
"license": "MIT",
"funding": "https://github.com/sponsors/wxt-dev",
"version": "1.0.2",
"version": "1.0.3",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"import": {
@@ -39,20 +39,18 @@
"dist"
],
"scripts": {
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"check": "pnpm build && check"
},
"peerDependencies": {
"wxt": ">=0.19.16"
},
"dependencies": {
"@vitejs/plugin-vue": "^5.2.3"
"@vitejs/plugin-vue": "^5.2.3 || ^6.0.0"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"wxt": "workspace:*"
}
}
+15
View File
@@ -0,0 +1,15 @@
import { defineConfig } from 'tsdown';
const entry = {
index: './src/index.ts',
};
export default defineConfig([
{
entry,
},
{
entry,
format: 'cjs',
},
]);
+33
View File
@@ -0,0 +1,33 @@
# Changelog
## v0.1.2
[compare changes](https://github.com/wxt-dev/wxt/compare/runner-v0.1.1...runner-v0.1.2)
### 🚀 Enhancements
- **config:** Add browser path for Zen via Homebrew ([#1813](https://github.com/wxt-dev/wxt/pull/1813))
### 🩹 Fixes
- Improve Chrome path search ([#1823](https://github.com/wxt-dev/wxt/pull/1823))
- **paths:** Add browser paths for Arc & Dia on macos ([#1814](https://github.com/wxt-dev/wxt/pull/1814))
### 🏡 Chore
- Fix auto-fixable `markdownlint` errors ([#1710](https://github.com/wxt-dev/wxt/pull/1710))
- Manually fix markdownlint errors ([#1711](https://github.com/wxt-dev/wxt/pull/1711))
- **deps:** Upgrade oxlint from 0.16.8 to 1.14.0 ([a01928e0](https://github.com/wxt-dev/wxt/commit/a01928e0))
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Sam Carlton ([@ThatGuySam](https://github.com/ThatGuySam))
- Alexander Kachkaev <alexander@kachkaev.ru>
## v0.1.1
[compare changes](https://github.com/wxt-dev/wxt/compare/runner-v0.1.0...runner-v0.1.1)
+6 -4
View File
@@ -2,7 +2,9 @@
Programmatically open a browser and install a web extension from a local directory.
###### With WXT
## Usage
### With WXT
> [!WARNING]
> This package is intended to replace [`web-ext`](https://github.com/mozilla/web-ext) in the future, but it is not ready at the moment. Once it's ready for testing in WXT, more details will be added here.
@@ -16,7 +18,7 @@ export default defineRunnerConfig({
});
```
###### JS API
### JS API
```ts
import { run } from '@wxt-dev/runner';
@@ -92,7 +94,7 @@ await run({
These presets configure different flags for different operating systems when spawning the browser process.
If you want to customize your data persistence beyond what these presets define, [you can override the browser flags yourself](#Arguments) to configure persistence.
If you want to customize your data persistence beyond what these presets define, [you can override the browser flags yourself](#arguments) to configure persistence.
### Browser Binaries
@@ -153,7 +155,7 @@ To see debug logs, set the `DEBUG` env var to `"@wxt-dev/runner"`. This will pri
<details>
<summary>Example debug output</summary>
```
```plaintext
@wxt-dev/runner:options User options: { extensionDir: 'demo-extension', target: undefined }
@wxt-dev/runner:options Resolved options: {
browserBinary: '/usr/bin/chromium',
+7 -11
View File
@@ -1,7 +1,7 @@
{
"name": "@wxt-dev/runner",
"description": "Launch Chrome and Firefox with a web extension installed",
"version": "0.1.0",
"version": "0.1.2",
"type": "module",
"repository": {
"type": "git",
@@ -24,21 +24,17 @@
"check": "pnpm build && check",
"test": "buildc --deps-only -- vitest",
"dev": "tsx --trace-warnings dev.ts",
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"prepublishOnly": "pnpm build"
},
"dependencies": {},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"oxlint": "^0.16.8",
"publint": "^0.3.12",
"tsx": "4.19.4",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"vitest": "^3.1.2"
"oxlint": "^1.43.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"vitest": "^4.0.18"
},
"main": "dist/index.mjs",
"types": "dist/index.d.ts",
"types": "dist/index.d.mts",
"exports": {
".": {
"types": "./dist/index.d.mts",
+25 -2
View File
@@ -1,11 +1,13 @@
export type BrowserPlatform = 'windows' | 'mac' | 'linux';
export type KnownTarget =
| 'arc'
| 'chromium'
| 'chrome'
| 'chrome-beta'
| 'chrome-dev'
| 'chrome-canary'
| 'dia'
| 'edge'
| 'edge-beta'
| 'edge-dev'
@@ -21,6 +23,11 @@ export const KNOWN_BROWSER_PATHS: Record<
> = {
// Chromium based targets
arc: {
mac: ['/Applications/Arc.app/Contents/MacOS/Arc'],
linux: [],
windows: [],
},
chromium: {
mac: [],
linux: [
@@ -30,7 +37,10 @@ export const KNOWN_BROWSER_PATHS: Record<
windows: [],
},
chrome: {
mac: ['/Applications/Chrome.app/Contents/MacOS/Google Chrome'],
mac: [
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
'/Applications/Chrome.app/Contents/MacOS/Google Chrome',
],
linux: [],
windows: ['C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'],
},
@@ -42,6 +52,7 @@ export const KNOWN_BROWSER_PATHS: Record<
'chrome-canary': {
mac: [
'/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
'/Applications/Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
],
linux: [],
windows: [],
@@ -51,6 +62,11 @@ export const KNOWN_BROWSER_PATHS: Record<
linux: [],
windows: [],
},
dia: {
mac: ['/Applications/Dia.app/Contents/MacOS/Dia'],
linux: [],
windows: [],
},
edge: {
mac: [],
linux: [],
@@ -96,7 +112,12 @@ export const KNOWN_BROWSER_PATHS: Record<
windows: [],
},
zen: {
mac: ['/Applications/Zen Browser.app/Contents/MacOS/zen'],
mac: [
'/Applications/Zen Browser.app/Contents/MacOS/zen',
// Homebrew Cask
// https://github.com/Homebrew/homebrew-cask/blob/main/Casks/z/zen.rb#L23C13-L23C19
'/Applications/Zen.app/Contents/MacOS/zen',
],
linux: [],
windows: [],
},
@@ -107,10 +128,12 @@ export const KNOWN_BROWSER_PATHS: Record<
*/
export const FALLBACK_TARGETS: Partial<Record<KnownTarget, KnownTarget[]>> = {
chrome: [
'arc',
'chromium',
'chrome-canary',
'chrome-beta',
'chrome-dev',
'dia',
'edge',
'edge-canary',
'edge-beta',
+56 -1
View File
@@ -1,5 +1,60 @@
# Changelog
## v1.2.6
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.5...storage-v1.2.6)
## v1.2.5
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.4...storage-v1.2.5)
## v1.2.4
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.3...storage-v1.2.4)
## v1.2.3
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.2...storage-v1.2.3)
## v1.2.2
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.1...storage-v1.2.2)
## v1.2.1
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.0...storage-v1.2.1)
## v1.2.0
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.1.1...storage-v1.2.0)
### 🚀 Enhancements
- **storage:** Add `onMigrationComplete` callback ([#1514](https://github.com/wxt-dev/wxt/pull/1514))
- **storage:** Add `debug` option to enable migration logs ([#1513](https://github.com/wxt-dev/wxt/pull/1513))
### 🩹 Fixes
- Fix typescript error on `defineItem` fallback ([#1601](https://github.com/wxt-dev/wxt/pull/1601))
- Use `@wxt-dev/browser` instead of `@types/chrome` ([#1645](https://github.com/wxt-dev/wxt/pull/1645))
### 🏡 Chore
- **deps:** Update all dependencies ([#1568](https://github.com/wxt-dev/wxt/pull/1568))
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
- Change browser workspace dependency to `^` ([c7335add](https://github.com/wxt-dev/wxt/commit/c7335add))
- **deps:** Upgrade oxlint from 0.16.8 to 1.14.0 ([a01928e0](https://github.com/wxt-dev/wxt/commit/a01928e0))
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Anh71me ([@iyume](https://github.com/iyume))
- Ergou <ma2808203259@hotmail.com>
## v1.1.1
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.1.0...storage-v1.1.1)
@@ -69,4 +124,4 @@ It's still shipped inside WXT and accessible via `wxt/storage`, but now:
[Read the docs](https://wxt.dev/storage.html) for more details.
> This is apart of the v1.0 initiative for WXT.
> This is apart of the v1.0 initiative for WXT.
+8 -10
View File
@@ -1,7 +1,7 @@
{
"name": "@wxt-dev/storage",
"description": "Web extension storage API provided by WXT, supports all browsers.",
"version": "1.1.1",
"version": "1.2.6",
"type": "module",
"repository": {
"type": "git",
@@ -25,7 +25,7 @@
"license": "MIT",
"funding": "https://github.com/sponsors/wxt-dev",
"scripts": {
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"check": "buildc --deps-only -- check",
"test": "buildc --deps-only -- vitest"
},
@@ -35,16 +35,14 @@
"dequal": "^2.0.3"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@webext-core/fake-browser": "^1.3.2",
"oxlint": "^0.16.8",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"vitest": "^3.1.2"
"@webext-core/fake-browser": "^1.3.4",
"oxlint": "^1.43.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"vitest": "^4.0.18"
},
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"types": "./dist/index.d.mts",
@@ -1315,6 +1315,18 @@ describe('Storage Utils', () => {
});
expectTypeOf(item).toEqualTypeOf<WxtStorageItem<number | null, {}>>();
});
it('should define a non-null value when options are passed with a non-null init function', () => {
const item = storage.defineItem(`local:test`, {
init: () => 123,
});
expectTypeOf(item).toEqualTypeOf<WxtStorageItem<number, {}>>();
const item2 = storage.defineItem(`local:test`, {
init: () => Promise.resolve(123),
});
expectTypeOf(item2).toEqualTypeOf<WxtStorageItem<number, {}>>();
});
});
});
+11 -2
View File
@@ -519,7 +519,7 @@ function createDriver(storageArea: StorageArea): WxtStorageDriver {
const watchListeners = new Set<(changes: StorageAreaChanges) => void>();
return {
getItem: async (key) => {
const res = await getStorageArea().get(key);
const res = await getStorageArea().get<Record<string, any>>(key);
return res[key];
},
getItems: async (keys) => {
@@ -560,7 +560,10 @@ function createDriver(storageArea: StorageArea): WxtStorageDriver {
},
watch(key, cb) {
const listener = (changes: StorageAreaChanges) => {
const change = changes[key];
const change = changes[key] as {
newValue?: any;
oldValue?: any | null;
} | null;
if (change == null) return;
if (dequal(change.newValue, change.oldValue)) return;
cb(change.newValue ?? null, change.oldValue ?? null);
@@ -749,6 +752,12 @@ export interface WxtStorage {
key: StorageItemKey,
options: WxtStorageItemOptions<TValue> & { defaultValue: TValue },
): WxtStorageItem<TValue, TMetadata>;
defineItem<TValue, TMetadata extends Record<string, unknown> = {}>(
key: StorageItemKey,
options: WxtStorageItemOptions<TValue> & {
init: () => TValue | Promise<TValue>;
},
): WxtStorageItem<TValue, TMetadata>;
defineItem<TValue, TMetadata extends Record<string, unknown> = {}>(
key: StorageItemKey,
options: WxtStorageItemOptions<TValue>,
+5 -7
View File
@@ -21,7 +21,7 @@
"license": "MIT",
"type": "module",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"types": "./dist/index.d.mts",
@@ -32,7 +32,7 @@
"dist"
],
"scripts": {
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"check": "buildc --deps-only -- check"
},
"peerDependencies": {
@@ -40,11 +40,9 @@
"wxt": ">=0.19.0"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"oxlint": "^0.16.8",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"oxlint": "^1.43.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"unocss": "^0.64.0 || ^0.65.0 || ^65.0.0 || ^66.0.0",
"wxt": "workspace:*"
},
@@ -1,15 +0,0 @@
import { defineBuildConfig } from 'unbuild';
import { resolve } from 'node:path';
export default defineBuildConfig({
rootDir: resolve(__dirname, 'modules/webextension-polyfill'),
outDir: resolve(__dirname, 'dist'),
entries: [
{ input: 'index.ts', name: 'index' },
{ input: 'browser.ts', name: 'browser' },
],
replace: {
'process.env.NPM': 'true',
},
declaration: true,
});
+5 -7
View File
@@ -20,7 +20,7 @@
"version": "1.0.0",
"type": "module",
"main": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"types": "./dist/index.d.mts",
@@ -37,7 +37,7 @@
"scripts": {
"dev": "wxt",
"check": "pnpm build && check",
"build": "buildc -- unbuild",
"build": "buildc -- tsdown",
"prepare": "buildc --deps-only -- wxt prepare"
},
"peerDependencies": {
@@ -45,11 +45,9 @@
"wxt": ">=0.20.0"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@types/webextension-polyfill": "^0.12.3",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"@types/webextension-polyfill": "^0.12.4",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"webextension-polyfill": "^0.12.0",
"wxt": "workspace:*"
}
@@ -0,0 +1,11 @@
import { defineConfig } from 'tsdown';
export default defineConfig({
entry: {
index: 'modules/webextension-polyfill/index.ts',
browser: 'modules/webextension-polyfill/browser.ts',
},
define: {
'process.env.NPM': 'true',
},
});
+8 -8
View File
@@ -18,19 +18,19 @@
},
"dependencies": {
"@wxt-dev/i18n": "workspace:*",
"react": "^19.1.0",
"react-dom": "^19.1.0"
"react": "^19.2.4",
"react-dom": "^19.2.4"
},
"devDependencies": {
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.3",
"@types/react": "^19.2.13",
"@types/react-dom": "^19.2.3",
"@wxt-dev/auto-icons": "workspace:*",
"@wxt-dev/unocss": "workspace:*",
"sass": "^1.87.0",
"typescript": "^5.8.3",
"sass": "^1.97.3",
"typescript": "^5.9.3",
"unocss": "^0.64.0 || ^0.65.0 || ^65.0.0 || ^66.0.0",
"vitest": "^3.1.2",
"vitest-plugin-random-seed": "^1.1.1",
"vitest": "^4.0.18",
"vitest-plugin-random-seed": "^1.1.2",
"wxt": "workspace:*"
},
"buildc": {
+216
View File
@@ -1,5 +1,221 @@
# Changelog
## v0.20.14
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.13...wxt-v0.20.14)
### 🚀 Enhancements
- Add `onBeforeMount` callback to `createIframeUi` options ([#1899](https://github.com/wxt-dev/wxt/pull/1899))
### 🩹 Fixes
- Remove failing test ([6fb4cee4](https://github.com/wxt-dev/wxt/commit/6fb4cee4))
- Rename and make firefoxPrefs in web-ext.config.ts work ([#2068](https://github.com/wxt-dev/wxt/pull/2068))
- **content-script-context:** Handle undefined browser.runtime ([#2042](https://github.com/wxt-dev/wxt/pull/2042))
- `MaxListenersExceededWarning` ([#2058](https://github.com/wxt-dev/wxt/pull/2058))
### 📖 Documentation
- Fix alignment of 2 last comments of regex patterns ([#2012](https://github.com/wxt-dev/wxt/pull/2012))
### 🏡 Chore
- Use `tsdown` to build packages ([#2006](https://github.com/wxt-dev/wxt/pull/2006))
- Move script-only dev dependencies to top-level `package.json` ([#2007](https://github.com/wxt-dev/wxt/pull/2007))
- Update dependencies ([#2069](https://github.com/wxt-dev/wxt/pull/2069))
- Upgrade major deps ([#2070](https://github.com/wxt-dev/wxt/pull/2070))
- Refresh lockfile and upgrade subdependencies ([#2071](https://github.com/wxt-dev/wxt/pull/2071))
### ❤️ Contributors
- Dareka ([@darekadareka](https://github.com/darekadareka))
- Mark ([@mjfaga](https://github.com/mjfaga))
- Ariasuni <aria@ariasuni.eu>
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Patryk Kuniczak ([@PatrykKuniczak](https://github.com/PatrykKuniczak))
- Bohuslavsemenov ([@bohuslavsemenov](https://github.com/bohuslavsemenov))
## v0.20.13
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.12...wxt-v0.20.13)
### 🚀 Enhancements
- Remove script element immediately in injectScript ([#1761](https://github.com/wxt-dev/wxt/pull/1761))
- Add `modifyScript` option to `injectScript` ([#1762](https://github.com/wxt-dev/wxt/pull/1762))
- Make `injectScript` return the created script element ([#1838](https://github.com/wxt-dev/wxt/pull/1838))
- Support `.wxtrc` config file ([#1833](https://github.com/wxt-dev/wxt/pull/1833))
### 🩹 Fixes
- Make `injectScript` wait until script is actually loaded ([#1763](https://github.com/wxt-dev/wxt/pull/1763))
- Don't return promises from unlisted scripts that do not have an async `main` function ([#1907](https://github.com/wxt-dev/wxt/pull/1907))
### 💅 Refactors
- Use `script.text` instead of `innerHTML` in `injectScript` ([#1764](https://github.com/wxt-dev/wxt/pull/1764))
### ❤️ Contributors
- Rxliuli ([@rxliuli](https://github.com/rxliuli))
- Sebastian Landwehr <info@sebastianlandwehr.com>
- Johan Kiviniemi ([@ion1](https://github.com/ion1))
## v0.20.12
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.11...wxt-v0.20.12)
### 🚀 Enhancements
- Remove `data-wxt-*` attributes ([#1913](https://github.com/wxt-dev/wxt/pull/1913))
- Default to using `use_dynamic_url: true` for content script css files ([#1993](https://github.com/wxt-dev/wxt/pull/1993))
### 🩹 Fixes
- Wxt normal logs are drowned by `dotenv@17.0.0` ads ([#1883](https://github.com/wxt-dev/wxt/pull/1883))
- Optimize `splitShadowRootCss` ([#1934](https://github.com/wxt-dev/wxt/pull/1934))
- `wxt prepare` fails with the error "__vite_ssr_exportName__ is not defined" when using Vite 7 ([#1884](https://github.com/wxt-dev/wxt/pull/1884))
### 🏡 Chore
- Use `linkedom` a test instead of `happy-dom` ([#1957](https://github.com/wxt-dev/wxt/pull/1957))
- Add support for `vite-node` v5 ([#2001](https://github.com/wxt-dev/wxt/pull/2001))
- Upgrade dev and non-major prod dependencies ([#2000](https://github.com/wxt-dev/wxt/pull/2000))
- **dev-deps:** Upgrade `happy-dom` to address CVE-2025-61927 ([#2002](https://github.com/wxt-dev/wxt/pull/2002))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Jaguar Zhou ([@aiktb](https://github.com/aiktb))
- Alexander Harding <noreply@harding.dev>
- Florian Kühne ([@ZerGo0](https://github.com/ZerGo0))
## v0.20.11
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.10...wxt-v0.20.11)
### 🩹 Fixes
- Split `wxt/testing` into separate modules to fix issues with `jsdom` and `happy-dom` ([#1844](https://github.com/wxt-dev/wxt/pull/1844))
- `input_components` is supported by mv3 ([#1881](https://github.com/wxt-dev/wxt/pull/1881))
### 🏡 Chore
- **deps:** Upgrade project subdependencies ([#1882](https://github.com/wxt-dev/wxt/pull/1882))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Qijia Liu <liumeo@pku.edu.cn>
- Marcellino Ornelas ([@marcellino-ornelas](https://github.com/marcellino-ornelas))
## v0.20.10
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.9...wxt-v0.20.10)
### 🏡 Chore
- **deps:** Upgrade non-breaking production dependencies ([#1877](https://github.com/wxt-dev/wxt/pull/1877))
- **deps:** Upgrade web-ext-run to support CDP ([#1879](https://github.com/wxt-dev/wxt/pull/1879))
- **deps:** `publish-browser-extension` upgrade ([#1880](https://github.com/wxt-dev/wxt/pull/1880))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
## v0.20.9
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.8...wxt-v0.20.9)
### 🩹 Fixes
- **types:** Use TType for DocumentEventMap key in ctx.addEventListener ([#1863](https://github.com/wxt-dev/wxt/pull/1863))
- Prevent Unlisted CSS from being excluded in the build when using CSS preprocessor ([#1590](https://github.com/wxt-dev/wxt/pull/1590))
### 🏡 Chore
- **deps:** Upgrade oxlint from 0.16.8 to 1.14.0 ([a01928e0](https://github.com/wxt-dev/wxt/commit/a01928e0))
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
- Upgrade nano-spawn to v1 ([5fefd8e0](https://github.com/wxt-dev/wxt/commit/5fefd8e0))
- Upgrade faker to v10 ([984568e0](https://github.com/wxt-dev/wxt/commit/984568e0))
- Upgrade dotenv to v17.2.2 ([380a9630](https://github.com/wxt-dev/wxt/commit/380a9630))
- Upgrade happy-dom to v18.0.1 ([c1c3d3b7](https://github.com/wxt-dev/wxt/commit/c1c3d3b7))
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
### ❤️ Contributors
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Kim Gyeongjae ([@PortalCube](https://github.com/PortalCube))
- Atomie CHEN <atomic_cwh@163.com>
## v0.20.8
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.7...wxt-v0.20.8)
### 🩹 Fixes
- Support http server websocket inside containers ([#1707](https://github.com/wxt-dev/wxt/pull/1707))
- Recreating keyboardShortcuts interface on file changes. ([#1465](https://github.com/wxt-dev/wxt/pull/1465))
- Fix bad regex from #1707 ([#1712](https://github.com/wxt-dev/wxt/pull/1712), [#1707](https://github.com/wxt-dev/wxt/issues/1707))
- Fix bundle variable assignment error with `rolldown-vite` ([#1715](https://github.com/wxt-dev/wxt/pull/1715))
- Support negation patterns when including/excluding files from ZIP files ([#1517](https://github.com/wxt-dev/wxt/pull/1517))
- **rolldown-compat:** Only apply footer to content and unlisted scripts via plugin ([#1793](https://github.com/wxt-dev/wxt/pull/1793))
- Init project should allow the .git folder to exist ([#1731](https://github.com/wxt-dev/wxt/pull/1731))
- Adding missing chromiumPort parameter in web-ext.ts to enable fixed port debugging ([#1818](https://github.com/wxt-dev/wxt/pull/1818))
### 📖 Documentation
- Fix API reference sidebar by naming new module ([eb0bffb5](https://github.com/wxt-dev/wxt/commit/eb0bffb5))
- Update JSDoc with ways to cancel timeouts and intervals set by content script context ([030f23d2](https://github.com/wxt-dev/wxt/commit/030f23d2))
### 🏡 Chore
- Fix auto-fixable `markdownlint` errors ([#1710](https://github.com/wxt-dev/wxt/pull/1710))
- Remove automd ([7d25110a](https://github.com/wxt-dev/wxt/commit/7d25110a))
- Wxt & @wxt-dev/module-vue support Vite 7 ([#1771](https://github.com/wxt-dev/wxt/pull/1771))
- Fix type error ([0333ce5c](https://github.com/wxt-dev/wxt/commit/0333ce5c))
### 🤖 CI
- Use matrix for test jobs ([#1708](https://github.com/wxt-dev/wxt/pull/1708))
### ❤️ Contributors
- Sylva <sylvain.lavabre@live.fr>
- Btea ([@btea](https://github.com/btea))
- Patryk Kuniczak ([@PatrykKuniczak](https://github.com/PatrykKuniczak))
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Ayu ([@ayu-exorcist](https://github.com/ayu-exorcist))
- Nishu ([@nishu-murmu](https://github.com/nishu-murmu))
## v0.20.7
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.6...wxt-v0.20.7)
### 🚀 Enhancements
- Add `@font-face` to be processed by `splitShadowRootCss` ([#1635](https://github.com/wxt-dev/wxt/pull/1635))
- Add DisableLoadExtensionCommandLineSwitch flag to Chromium runner ([#1698](https://github.com/wxt-dev/wxt/pull/1698))
### 🩹 Fixes
- Improve CSS reset inside shadow roots ([da5cd325](https://github.com/wxt-dev/wxt/commit/da5cd325))
### 🏡 Chore
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
- **deps:** Update all dependencies ([#1648](https://github.com/wxt-dev/wxt/pull/1648))
- Change browser workspace dependency to `^` ([c7335add](https://github.com/wxt-dev/wxt/commit/c7335add))
### ❤️ Contributors
- Richard Lee ([@dlackty](https://github.com/dlackty))
- Aaron ([@aklinker1](https://github.com/aklinker1))
- Seaders ([@seaders](https://github.com/seaders))
## v0.20.6
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.5...wxt-v0.20.6)
+18 -44
View File
@@ -1,51 +1,33 @@
<!-- DO NOT EDIT, THIS FILE WAS GENERATED BY '../../scripts/generate-readmes.sh' -->
<h1 align="center">
<img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo">
<span>WXT</span>
</h1>
<div align="center">
<p align="center">
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="npm version" src="https://img.shields.io/npm/v/wxt?labelColor=black&color=%234fa048"></a>
<span> </span>
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="downloads" src="https://img.shields.io/npm/dm/wxt?labelColor=black&color=%234fa048"></a>
<span> </span>
<a href="https://github.com/wxt-dev/wxt/blob/main/LICENSE" target="_blank"><img alt="license | MIT" src="https://img.shields.io/npm/l/wxt?labelColor=black&color=%234fa048"></a>
<span> </span>
<a href="https://codecov.io/github/wxt-dev/wxt" target="_blank"><img alt="coverage" src="https://img.shields.io/codecov/c/github/wxt-dev/wxt?labelColor=black&color=%234fa048"></a>
</p>
# <img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo"> WXT
<p align="center">
<span>Next-gen framework for developing web extensions.</span>
<br/>
<span>⚡</span>
<br/>
<q><i>It's like Nuxt, but for Web Extensions</i></q>
</p>
[![npm version](https://img.shields.io/npm/v/wxt?labelColor=black&color=%234fa048)](https://www.npmjs.com/package/wxt)
[![downloads](https://img.shields.io/npm/dm/wxt?labelColor=black&color=%234fa048)](https://www.npmjs.com/package/wxt)
[![license | MIT](https://img.shields.io/npm/l/wxt?labelColor=black&color=%234fa048)](https://github.com/wxt-dev/wxt/blob/main/LICENSE)
[![coverage](https://img.shields.io/codecov/c/github/wxt-dev/wxt?labelColor=black&color=%234fa048)](https://codecov.io/github/wxt-dev/wxt)
<p align="center">
<a href="https://wxt.dev/guide/installation.html" target="_blank">Get Started</a>
&bull;
<a href="https://wxt.dev/api/config.html" target="_blank">Configuration</a>
&bull;
<a href="https://wxt.dev/examples.html" target="_blank">Examples</a>
&bull;
<a href="https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md" target="_blank">Changelog</a>
&bull;
<a href="https://discord.gg/ZFsZqGery9" target="_blank">Discord</a>
</p>
Next-gen framework for developing web extensions.<br/>⚡<br/><q><i>It's like Nuxt, but for Web Extensions</i></q>
[Get Started](https://wxt.dev/guide/installation.html) •
[Configuration](https://wxt.dev/api/config.html) •
[Examples](https://wxt.dev/examples.html) •
[Changelog](https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md) •
[Discord](https://discord.gg/ZFsZqGery9)
</div>
![Example CLI Output](https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/assets/cli-output.png)
## Demo
https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
<https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94>
## Quick Start
Bootstrap a new project:
<!-- automd:pm-x version="latest" name="wxt" args="init" -->
```sh
# npm
npx wxt@latest init
@@ -57,8 +39,6 @@ pnpm dlx wxt@latest init
bunx wxt@latest init
```
<!-- /automd -->
Or see the [installation guide](https://wxt.dev/guide/installation.html) to get started with WXT.
## Features
@@ -80,17 +60,11 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get
WXT is a [MIT-licensed](https://github.com/wxt-dev/wxt/blob/main/LICENSE) open source project with its ongoing development made possible entirely by the support of these awesome backers. If you'd like to join them, please consider [sponsoring WXT's development](https://github.com/sponsors/wxt-dev).
<a href="https://github.com/sponsors/wxt-dev"><img alt="WXT Sponsors" src="https://raw.githubusercontent.com/wxt-dev/static/refs/heads/main/sponsorkit/sponsors.svg"></a>
[![WXT Sponsors](https://raw.githubusercontent.com/wxt-dev/static/refs/heads/main/sponsorkit/sponsors.svg)](https://github.com/sponsors/wxt-dev)
## Contributors
<!-- automd:contributors author="aklinker1" license="MIT" github="wxt-dev/wxt" -->
Published under the [MIT](https://github.com/wxt-dev/wxt/blob/main/LICENSE) license.
Made by [@aklinker1](https://github.com/aklinker1) and [community](https://github.com/wxt-dev/wxt/graphs/contributors) 💛
<br><br>
<a href="https://github.com/wxt-dev/wxt/graphs/contributors">
<img src="https://contrib.rocks/image?repo=wxt-dev/wxt" />
</a>
<!-- /automd -->
[![WXT contributors](https://contrib.rocks/image?repo=wxt-dev/wxt)](https://github.com/wxt-dev/wxt/graphs/contributors)
-46
View File
@@ -1,46 +0,0 @@
import { defineBuildConfig } from 'unbuild';
import { version, exports } from './package.json';
import { readFile, writeFile } from 'fs/promises';
import {
virtualEntrypointModuleNames,
virtualModuleNames,
} from './src/core/utils/virtual-modules';
export default defineBuildConfig([
// Non-virtual modules can be transpiled with mkdist
{
entries: [
{
builder: 'mkdist',
input: 'src',
pattern: ['**/*', '!**/__tests__', '!**/*.md', '!virtual', '!@types'],
declaration: true,
},
],
hooks: {
async 'build:done'() {
// Replace any template variables in output files
await replaceVars('dist/version.mjs', { version });
},
},
},
// Virtual modules must be bundled individually
...virtualModuleNames.map((moduleName) => ({
entries: [`src/virtual/${moduleName}.ts`],
externals: [
...virtualEntrypointModuleNames.map((name) => `virtual:user-${name}`),
'virtual:wxt-plugins',
'virtual:app-config',
...Object.keys(exports).map((path) => 'wxt' + path.slice(1)), // ./utils/storage => wxt/utils/storage
],
})),
]);
async function replaceVars(file: string, vars: Record<string, string>) {
let text = await readFile(file, 'utf8');
Object.entries(vars).forEach(([name, value]) => {
text = text.replaceAll(`{{${name}}}`, value);
});
await writeFile(file, text, 'utf8');
}
+16 -30
View File
@@ -17,22 +17,22 @@ describe('Auto Imports', () => {
// Generated by wxt
export {}
declare global {
const ContentScriptContext: typeof import('wxt/utils/content-script-context')['ContentScriptContext']
const InvalidMatchPattern: typeof import('wxt/utils/match-patterns')['InvalidMatchPattern']
const MatchPattern: typeof import('wxt/utils/match-patterns')['MatchPattern']
const browser: typeof import('wxt/browser')['browser']
const createIframeUi: typeof import('wxt/utils/content-script-ui/iframe')['createIframeUi']
const createIntegratedUi: typeof import('wxt/utils/content-script-ui/integrated')['createIntegratedUi']
const createShadowRootUi: typeof import('wxt/utils/content-script-ui/shadow-root')['createShadowRootUi']
const defineAppConfig: typeof import('wxt/utils/define-app-config')['defineAppConfig']
const defineBackground: typeof import('wxt/utils/define-background')['defineBackground']
const defineContentScript: typeof import('wxt/utils/define-content-script')['defineContentScript']
const defineUnlistedScript: typeof import('wxt/utils/define-unlisted-script')['defineUnlistedScript']
const defineWxtPlugin: typeof import('wxt/utils/define-wxt-plugin')['defineWxtPlugin']
const fakeBrowser: typeof import('wxt/testing')['fakeBrowser']
const injectScript: typeof import('wxt/utils/inject-script')['injectScript']
const storage: typeof import('wxt/utils/storage')['storage']
const useAppConfig: typeof import('wxt/utils/app-config')['useAppConfig']
const ContentScriptContext: typeof import('wxt/utils/content-script-context').ContentScriptContext
const InvalidMatchPattern: typeof import('wxt/utils/match-patterns').InvalidMatchPattern
const MatchPattern: typeof import('wxt/utils/match-patterns').MatchPattern
const browser: typeof import('wxt/browser').browser
const createIframeUi: typeof import('wxt/utils/content-script-ui/iframe').createIframeUi
const createIntegratedUi: typeof import('wxt/utils/content-script-ui/integrated').createIntegratedUi
const createShadowRootUi: typeof import('wxt/utils/content-script-ui/shadow-root').createShadowRootUi
const defineAppConfig: typeof import('wxt/utils/define-app-config').defineAppConfig
const defineBackground: typeof import('wxt/utils/define-background').defineBackground
const defineContentScript: typeof import('wxt/utils/define-content-script').defineContentScript
const defineUnlistedScript: typeof import('wxt/utils/define-unlisted-script').defineUnlistedScript
const defineWxtPlugin: typeof import('wxt/utils/define-wxt-plugin').defineWxtPlugin
const fakeBrowser: typeof import('wxt/testing').fakeBrowser
const injectScript: typeof import('wxt/utils/inject-script').injectScript
const storage: typeof import('wxt/utils/storage').storage
const useAppConfig: typeof import('wxt/utils/app-config').useAppConfig
}
// for type re-export
declare global {
@@ -288,20 +288,6 @@ describe('Auto Imports', () => {
);
});
it('should NOT output an ESlint config file by default', async () => {
const project = new TestProject();
project.addFile('entrypoints/popup.html', `<html></html>`);
await project.prepare();
expect(await project.fileExists('.wxt/eslint-auto-imports.mjs')).toBe(
false,
);
expect(await project.fileExists('.wxt/eslintrc-auto-import.json')).toBe(
false,
);
});
it('should allow customizing the output', async () => {
const project = new TestProject();
project.addFile('entrypoints/popup.html', `<html></html>`);
+1 -1
View File
@@ -298,7 +298,7 @@ describe('Module Helpers', () => {
await expect(
project.serializeFile('.wxt/types/imports.d.ts'),
).resolves.toContain("const ref: typeof import('vue')['ref']");
).resolves.toContain("const ref: typeof import('vue').ref");
});
});
});
+145 -87
View File
@@ -1,4 +1,4 @@
import { describe, it, expect } from 'vitest';
import { describe, expect, it } from 'vitest';
import { TestProject } from '../utils';
describe('Output Directory Structure', () => {
@@ -220,6 +220,77 @@ describe('Output Directory Structure', () => {
expect(await project.fileExists('.output/chrome-mv3/unlisted.js'));
});
it('should support CSS entrypoints', async () => {
const project = new TestProject();
project.addFile(
'entrypoints/plain-one.css',
`body {
font: 100% Helvetica, sans-serif;
color: #333;
}`,
);
project.addFile(
'entrypoints/plain-two.content.css',
`body {
font: 100% Helvetica, sans-serif;
color: #333;
}`,
);
project.addFile(
'entrypoints/sass-one.scss',
`$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}`,
);
project.addFile(
'entrypoints/sass-two.content.scss',
`$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}`,
);
await project.build();
expect(await project.serializeOutput(['.output/chrome-mv3/manifest.json']))
.toMatchInlineSnapshot(`
".output/chrome-mv3/assets/plain-one.css
----------------------------------------
body{font:100% Helvetica,sans-serif;color:#333}
================================================================================
.output/chrome-mv3/assets/sass-one.css
----------------------------------------
body{font:100% Helvetica,sans-serif;color:#333}
================================================================================
.output/chrome-mv3/content-scripts/plain-two.css
----------------------------------------
body{font:100% Helvetica,sans-serif;color:#333}
================================================================================
.output/chrome-mv3/content-scripts/sass-two.css
----------------------------------------
body{font:100% Helvetica,sans-serif;color:#333}
================================================================================
.output/chrome-mv3/manifest.json
----------------------------------------
<contents-ignored>"
`);
});
it("should output to a custom directory when overriding 'outDir'", async () => {
const project = new TestProject();
project.addFile('entrypoints/unlisted.html', '<html></html>');
@@ -272,45 +343,40 @@ describe('Output Directory Structure', () => {
expect(await project.serializeFile('.output/chrome-mv3/background.js'))
.toMatchInlineSnapshot(`
".output/chrome-mv3/background.js
----------------------------------------
var _a, _b;
import { l as logHello, i as initPlugins } from "./chunks/_virtual_wxt-plugins-OjKtWpmY.js";
function defineBackground(arg) {
if (arg == null || typeof arg === "function") return { main: arg };
return arg;
}
const definition = defineBackground({
type: "module",
main() {
logHello("background");
".output/chrome-mv3/background.js
----------------------------------------
import { l as logHello, i as initPlugins } from "./chunks/_virtual_wxt-plugins-OjKtWpmY.js";
function defineBackground(arg) {
if (arg == null || typeof arg === "function") return { main: arg };
return arg;
}
});
((_b = (_a = globalThis.browser) == null ? void 0 : _a.runtime) == null ? void 0 : _b.id) ? globalThis.browser : globalThis.chrome;
function print(method, ...args) {
return;
}
const logger = {
debug: (...args) => print(console.debug, ...args),
log: (...args) => print(console.log, ...args),
warn: (...args) => print(console.warn, ...args),
error: (...args) => print(console.error, ...args)
};
let result;
try {
initPlugins();
result = definition.main();
if (result instanceof Promise) {
console.warn(
"The background's main() function return a promise, but it must be synchronous"
);
const definition = defineBackground({
type: "module",
main() {
logHello("background");
}
});
globalThis.browser?.runtime?.id ? globalThis.browser : globalThis.chrome;
function print(method, ...args) {
return;
}
} catch (err) {
logger.error("The background crashed on startup!");
throw err;
}
"
`);
const logger = {
debug: (...args) => print(console.debug, ...args),
log: (...args) => print(console.log, ...args),
warn: (...args) => print(console.warn, ...args),
error: (...args) => print(console.error, ...args)
};
let result;
try {
initPlugins();
result = definition.main();
if (result instanceof Promise) console.warn("The background's main() function return a promise, but it must be synchronous");
} catch (err) {
logger.error("The background crashed on startup!");
throw err;
}
"
`);
});
it('should generate IIFE background script when type=undefined', async () => {
@@ -350,55 +416,47 @@ describe('Output Directory Structure', () => {
expect(await project.serializeFile('.output/chrome-mv3/background.js'))
.toMatchInlineSnapshot(`
".output/chrome-mv3/background.js
----------------------------------------
var background = function() {
"use strict";
var _a, _b;
function defineBackground(arg) {
if (arg == null || typeof arg === "function") return { main: arg };
return arg;
".output/chrome-mv3/background.js
----------------------------------------
var background = (function() {
"use strict";
function defineBackground(arg) {
if (arg == null || typeof arg === "function") return { main: arg };
return arg;
}
function logHello(name) {
console.log(\`Hello \${name}!\`);
}
const definition = defineBackground({
main() {
logHello("background");
}
function logHello(name) {
console.log(\`Hello \${name}!\`);
}
background;
const definition = defineBackground({
main() {
logHello("background");
}
});
background;
function initPlugins() {
}
((_b = (_a = globalThis.browser) == null ? void 0 : _a.runtime) == null ? void 0 : _b.id) ? globalThis.browser : globalThis.chrome;
function print(method, ...args) {
return;
}
const logger = {
debug: (...args) => print(console.debug, ...args),
log: (...args) => print(console.log, ...args),
warn: (...args) => print(console.warn, ...args),
error: (...args) => print(console.error, ...args)
};
let result;
try {
initPlugins();
result = definition.main();
if (result instanceof Promise) {
console.warn(
"The background's main() function return a promise, but it must be synchronous"
);
}
} catch (err) {
logger.error("The background crashed on startup!");
throw err;
}
const result$1 = result;
return result$1;
}();
background;
"
`);
});
function initPlugins() {
}
globalThis.browser?.runtime?.id ? globalThis.browser : globalThis.chrome;
function print(method, ...args) {
return;
}
const logger = {
debug: (...args) => print(console.debug, ...args),
log: (...args) => print(console.log, ...args),
warn: (...args) => print(console.warn, ...args),
error: (...args) => print(console.error, ...args)
};
let result;
try {
initPlugins();
result = definition.main();
if (result instanceof Promise) console.warn("The background's main() function return a promise, but it must be synchronous");
} catch (err) {
logger.error("The background crashed on startup!");
throw err;
}
var background_entrypoint_default = result;
return background_entrypoint_default;
})();
"
`);
});
});
+1 -1
View File
@@ -16,7 +16,7 @@ describe('Remote Code', () => {
const output = await project.serializeFile('.output/chrome-mv3/popup.js');
expect(output).toContain(
// Some text that will hopefully be in future versions of this script
'lodash.com',
'__lodash_placeholder__',
);
expect(output).not.toContain(url);
expect(
+3 -5
View File
@@ -139,17 +139,15 @@ describe('User Config', () => {
).toBe(true);
});
it('should throw error when config file not exist', async () => {
it('should not throw error when config file not exist', async () => {
const project = new TestProject();
project.addFile(
'src/entrypoints/background.ts',
'entrypoints/background.ts',
`export default defineBackground(
() => console.log('Hello background'),
);`,
);
await expect(
project.build({ configFile: 'foo.config.ts' }),
).rejects.toThrowError(/not found/);
await project.build({ configFile: 'foo.config.ts' });
});
});
+22
View File
@@ -285,4 +285,26 @@ describe('Zipping', () => {
expect(await project.fileExists(sourcesZip)).toBe(false);
},
);
it('should include files in the zip when negated in zip.exclude', async () => {
const project = new TestProject({
name: 'test',
version: '1.0.0',
});
project.addFile(
'entrypoints/background.ts',
'export default defineBackground(() => {});',
);
const unzipDir = project.resolvePath('.output/test-1.0.0-chrome');
const sourcesZip = project.resolvePath('.output/test-1.0.0-chrome.zip');
await project.zip({
zip: {
exclude: ['**/*.json', '!manifest.json'],
},
});
await extract(sourcesZip, { dir: unzipDir });
expect(await project.fileExists(unzipDir, 'manifest.json')).toBe(true);
});
});
+64 -58
View File
@@ -1,84 +1,82 @@
{
"name": "wxt",
"type": "module",
"version": "0.20.6",
"version": "0.20.14",
"description": "⚡ Next-gen Web Extension Framework",
"license": "MIT",
"scripts": {
"wxt": "tsx src/cli/index.ts",
"build": "buildc -- unbuild",
"build": "buildc -- tsdown --config-loader unrun",
"check": "pnpm build && pnpm run --reporter-hide-prefix /^check:.*/",
"check:default": "check",
"check:tsc-virtual": "tsc --noEmit -p src/virtual",
"test": "buildc --deps-only -- vitest",
"test:coverage": "pnpm test -- run --coverage",
"test:coverage": "pnpm test run --coverage",
"sync-releases": "pnpx changelogen@latest gh release",
"prepack": "pnpm build"
},
"dependencies": {
"@1natsu/wait-element": "^4.1.2",
"@aklinker1/rollup-plugin-visualizer": "5.12.0",
"@webext-core/fake-browser": "^1.3.2",
"@webext-core/isolated-element": "^1.1.2",
"@webext-core/fake-browser": "^1.3.4",
"@webext-core/isolated-element": "^1.1.3",
"@webext-core/match-patterns": "^1.0.3",
"@wxt-dev/browser": "workspace:^",
"@wxt-dev/storage": "workspace:^1.0.0",
"async-mutex": "^0.5.0",
"c12": "^3.0.3",
"c12": "^3.3.3",
"cac": "^6.7.14",
"chokidar": "^4.0.3",
"ci-info": "^4.2.0",
"chokidar": "^5.0.0",
"ci-info": "^4.4.0",
"consola": "^3.4.2",
"defu": "^6.1.4",
"dotenv": "^16.5.0",
"dotenv-expand": "^12.0.2",
"esbuild": "^0.25.0",
"dotenv": "^17.2.4",
"dotenv-expand": "^12.0.3",
"esbuild": "^0.27.1",
"fast-glob": "^3.3.3",
"filesize": "^10.1.6",
"fs-extra": "^11.3.0",
"get-port-please": "^3.1.2",
"giget": "^1.2.3 || ^2.0.0",
"hookable": "^5.5.3",
"import-meta-resolve": "^4.1.0",
"filesize": "^11.0.13",
"fs-extra": "^11.3.3",
"get-port-please": "^3.2.0",
"giget": "^1.2.3 || ^2.0.0 || ^3.0.0",
"hookable": "^6.0.1",
"import-meta-resolve": "^4.2.0",
"is-wsl": "^3.1.0",
"json5": "^2.2.3",
"jszip": "^3.10.1",
"linkedom": "^0.18.10",
"magicast": "^0.3.5",
"minimatch": "^10.0.1",
"nano-spawn": "^0.2.0",
"linkedom": "^0.18.12",
"magicast": "^0.5.2",
"minimatch": "^10.1.2",
"nano-spawn": "^2.0.0",
"normalize-path": "^3.0.0",
"nypm": "^0.6.0",
"nypm": "^0.6.5",
"ohash": "^2.0.11",
"open": "^10.1.2",
"ora": "^8.2.0",
"perfect-debounce": "^1.0.0",
"open": "^11.0.0",
"ora": "^9.3.0",
"perfect-debounce": "^2.1.0",
"picocolors": "^1.1.1",
"prompts": "^2.4.2",
"publish-browser-extension": "^2.3.0 || ^3.0.0",
"publish-browser-extension": "^2.3.0 || ^3.0.2 || ^4.0.0",
"scule": "^1.3.0",
"unimport": "^3.13.1 || ^4.0.0 || ^5.0.0",
"vite": "^5.4.19 || ^6.3.4",
"vite-node": "^2.1.4 || ^3.1.2",
"web-ext-run": "^0.2.3"
"vite": "^5.4.19 || ^6.3.4 || ^7.0.0",
"vite-node": "^3.2.4 || ^5.0.0",
"web-ext-run": "^0.2.4"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@faker-js/faker": "^9.7.0",
"@faker-js/faker": "^10.2.0",
"@types/fs-extra": "^11.0.4",
"@types/lodash.merge": "^4.6.9",
"@types/node": "^20.17.6",
"@types/normalize-path": "^3.0.2",
"@types/prompts": "^2.4.9",
"extract-zip": "^2.0.1",
"happy-dom": "^17.4.6",
"happy-dom": "^20.5.0",
"lodash.merge": "^4.6.2",
"oxlint": "^0.16.8",
"publint": "^0.3.12",
"typescript": "^5.8.3",
"unbuild": "^3.5.0",
"vitest": "^3.1.2",
"vitest-plugin-random-seed": "^1.1.1"
"oxlint": "^1.43.0",
"publint": "^0.3.17",
"typescript": "^5.9.3",
"vitest": "^4.0.18",
"vitest-plugin-random-seed": "^1.1.2"
},
"peerDependenciesMeta": {},
"repository": {
@@ -109,85 +107,93 @@
"wxt-publish-extension": "./bin/wxt-publish-extension.cjs"
},
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
},
"./utils/app-config": {
"types": "./dist/utils/app-config.d.ts",
"types": "./dist/utils/app-config.d.mts",
"default": "./dist/utils/app-config.mjs"
},
"./utils/inject-script": {
"types": "./dist/utils/inject-script.d.ts",
"types": "./dist/utils/inject-script.d.mts",
"default": "./dist/utils/inject-script.mjs"
},
"./utils/content-script-context": {
"types": "./dist/utils/content-script-context.d.ts",
"types": "./dist/utils/content-script-context.d.mts",
"default": "./dist/utils/content-script-context.mjs"
},
"./utils/content-script-ui/types": {
"types": "./dist/utils/content-script-ui/types.d.ts",
"types": "./dist/utils/content-script-ui/types.d.mts",
"default": "./dist/utils/content-script-ui/types.mjs"
},
"./utils/content-script-ui/integrated": {
"types": "./dist/utils/content-script-ui/integrated.d.ts",
"types": "./dist/utils/content-script-ui/integrated.d.mts",
"default": "./dist/utils/content-script-ui/integrated.mjs"
},
"./utils/content-script-ui/shadow-root": {
"types": "./dist/utils/content-script-ui/shadow-root.d.ts",
"types": "./dist/utils/content-script-ui/shadow-root.d.mts",
"default": "./dist/utils/content-script-ui/shadow-root.mjs"
},
"./utils/content-script-ui/iframe": {
"types": "./dist/utils/content-script-ui/iframe.d.ts",
"types": "./dist/utils/content-script-ui/iframe.d.mts",
"default": "./dist/utils/content-script-ui/iframe.mjs"
},
"./utils/define-app-config": {
"types": "./dist/utils/define-app-config.d.ts",
"types": "./dist/utils/define-app-config.d.mts",
"default": "./dist/utils/define-app-config.mjs"
},
"./utils/define-background": {
"types": "./dist/utils/define-background.d.ts",
"types": "./dist/utils/define-background.d.mts",
"default": "./dist/utils/define-background.mjs"
},
"./utils/define-content-script": {
"types": "./dist/utils/define-content-script.d.ts",
"types": "./dist/utils/define-content-script.d.mts",
"default": "./dist/utils/define-content-script.mjs"
},
"./utils/define-unlisted-script": {
"types": "./dist/utils/define-unlisted-script.d.ts",
"types": "./dist/utils/define-unlisted-script.d.mts",
"default": "./dist/utils/define-unlisted-script.mjs"
},
"./utils/define-wxt-plugin": {
"types": "./dist/utils/define-wxt-plugin.d.ts",
"types": "./dist/utils/define-wxt-plugin.d.mts",
"default": "./dist/utils/define-wxt-plugin.mjs"
},
"./utils/match-patterns": {
"types": "./dist/utils/match-patterns.d.ts",
"types": "./dist/utils/match-patterns.d.mts",
"default": "./dist/utils/match-patterns.mjs"
},
"./utils/split-shadow-root-css": {
"types": "./dist/utils/split-shadow-root-css.d.ts",
"types": "./dist/utils/split-shadow-root-css.d.mts",
"default": "./dist/utils/split-shadow-root-css.mjs"
},
"./utils/storage": {
"types": "./dist/utils/storage.d.ts",
"types": "./dist/utils/storage.d.mts",
"default": "./dist/utils/storage.mjs"
},
"./browser": {
"types": "./dist/browser.d.ts",
"types": "./dist/browser.d.mts",
"default": "./dist/browser.mjs"
},
"./testing/fake-browser": {
"types": "./dist/testing/fake-browser.d.mts",
"default": "./dist/testing/fake-browser.mjs"
},
"./testing/vitest-plugin": {
"types": "./dist/testing/wxt-vitest-plugin.d.mts",
"default": "./dist/testing/wxt-vitest-plugin.mjs"
},
"./testing": {
"types": "./dist/testing/index.d.ts",
"types": "./dist/testing/index.d.mts",
"default": "./dist/testing/index.mjs"
},
"./vite-builder-env": {
"types": "./dist/vite-builder-env.d.ts"
},
"./modules": {
"types": "./dist/modules.d.ts",
"types": "./dist/modules.d.mts",
"default": "./dist/modules.mjs"
}
}
+95 -18
View File
@@ -2,6 +2,7 @@ import type * as vite from 'vite';
import {
BuildStepOutput,
Entrypoint,
EntrypointGroup,
ResolvedConfig,
WxtBuilder,
WxtBuilderServer,
@@ -24,7 +25,9 @@ import { ViteNodeServer } from 'vite-node/server';
import { ViteNodeRunner } from 'vite-node/client';
import { installSourcemapsSupport } from 'vite-node/source-map';
import { createExtensionEnvironment } from '../../utils/environments';
import { relative } from 'node:path';
import { dirname, extname, join, relative } from 'node:path';
import fs from 'fs-extra';
import { normalizePath } from '../../utils/paths';
export async function createViteBuilder(
wxtConfig: ResolvedConfig,
@@ -106,6 +109,8 @@ export async function createViteBuilder(
const plugins: NonNullable<vite.UserConfig['plugins']> = [
wxtPlugins.entrypointGroupGlobals(entrypoint),
];
const iifeReturnValueName = safeVarName(entrypoint.name);
if (
entrypoint.type === 'content-script-style' ||
entrypoint.type === 'unlisted-style'
@@ -113,17 +118,16 @@ export async function createViteBuilder(
plugins.push(wxtPlugins.cssEntrypoints(entrypoint, wxtConfig));
}
const iifeReturnValueName = safeVarName(entrypoint.name);
const libMode: vite.UserConfig = {
if (
entrypoint.type === 'content-script' ||
entrypoint.type === 'unlisted-script'
) {
plugins.push(wxtPlugins.iifeFooter(iifeReturnValueName));
}
return {
mode: wxtConfig.mode,
plugins,
esbuild: {
// Add a footer with the returned value so it can return values to `scripting.executeScript`
// Footer is added a part of esbuild to make sure it's not minified. It
// get's removed if added to `build.rollupOptions.output.footer`
// See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/executeScript#return_value
footer: iifeReturnValueName + ';',
},
build: {
lib: {
entry,
@@ -159,8 +163,7 @@ export async function createViteBuilder(
// See https://github.com/aklinker1/vite-plugin-web-extension/issues/96
'process.env.NODE_ENV': JSON.stringify(wxtConfig.mode),
},
};
return libMode;
} satisfies vite.UserConfig;
};
/**
@@ -172,10 +175,7 @@ export async function createViteBuilder(
);
return {
mode: wxtConfig.mode,
plugins: [
wxtPlugins.multipageMove(entrypoints, wxtConfig),
wxtPlugins.entrypointGroupGlobals(entrypoints),
],
plugins: [wxtPlugins.entrypointGroupGlobals(entrypoints)],
build: {
rollupOptions: {
input: entrypoints.reduce<Record<string, string>>((input, entry) => {
@@ -308,7 +308,10 @@ export async function createViteBuilder(
async build(group) {
let entryConfig;
if (Array.isArray(group)) entryConfig = getMultiPageConfig(group);
else if (group.inputPath.endsWith('.css'))
else if (
group.type === 'content-script-style' ||
group.type === 'unlisted-style'
)
entryConfig = getCssConfig(group);
else entryConfig = getLibModeConfig(group);
@@ -319,9 +322,10 @@ export async function createViteBuilder(
buildConfig,
);
const result = await vite.build(buildConfig);
const chunks = getBuildOutputChunks(result);
return {
entrypoints: group,
chunks: getBuildOutputChunks(result),
chunks: await moveHtmlFiles(wxtConfig, group, chunks),
};
},
async createServer(info) {
@@ -400,3 +404,76 @@ function getRollupEntry(entrypoint: Entrypoint): string {
}
return entrypoint.inputPath;
}
/**
* Ensures the HTML files output by a multipage build are in the correct location. This does two
* things:
*
* 1. Moves the HTML files to their final location at `<outDir>/<entrypoint.name>.html`.
* 2. Updates the bundle so it summarizes the files correctly in the returned build output.
*
* Assets (JS and CSS) are output to the `<outDir>/assets` directory, and don't need to be modified.
* HTML files access them via absolute URLs, so we don't need to update any import paths in the HTML
* files either.
*/
async function moveHtmlFiles(
config: ResolvedConfig,
group: EntrypointGroup,
chunks: BuildStepOutput['chunks'],
): Promise<BuildStepOutput['chunks']> {
if (!Array.isArray(group)) return chunks;
const entryMap = group.reduce<Record<string, Entrypoint>>((map, entry) => {
const a = normalizePath(relative(config.root, entry.inputPath));
map[a] = entry;
return map;
}, {});
const movedChunks = await Promise.all(
chunks.map(async (chunk) => {
if (!chunk.fileName.endsWith('.html')) return chunk;
const entry = entryMap[chunk.fileName];
const oldBundlePath = chunk.fileName;
const newBundlePath = getEntrypointBundlePath(
entry,
config.outDir,
extname(chunk.fileName),
);
const oldAbsPath = join(config.outDir, oldBundlePath);
const newAbsPath = join(config.outDir, newBundlePath);
await fs.ensureDir(dirname(newAbsPath));
await fs.move(oldAbsPath, newAbsPath, { overwrite: true });
return {
...chunk,
fileName: newBundlePath,
};
}),
);
// TODO: Optimize and only delete old path directories
removeEmptyDirs(config.outDir);
return movedChunks;
}
/**
* Recursively remove all directories that are empty/
*/
export async function removeEmptyDirs(dir: string): Promise<void> {
const files = await fs.readdir(dir);
for (const file of files) {
const filePath = join(dir, file);
const stats = await fs.stat(filePath);
if (stats.isDirectory()) {
await removeEmptyDirs(filePath);
}
}
try {
await fs.rmdir(dir);
} catch {
// noop on failure - this means the directory was not empty.
}
}
@@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest';
import { Window } from 'happy-dom';
import { pointToDevServer } from '../devHtmlPrerender';
import {
fakeDevServer,
@@ -7,6 +6,7 @@ import {
} from '../../../../utils/testing/fake-objects';
import { normalizePath } from '../../../../utils/paths';
import { resolve } from 'node:path';
import { parseHTML } from 'linkedom';
describe('Dev HTML Prerender Plugin', () => {
describe('pointToDevServer', () => {
@@ -32,9 +32,7 @@ describe('Dev HTML Prerender Plugin', () => {
// URLs should not be changed
['https://example.com/style.css', 'https://example.com/style.css'],
])('should transform "%s" into "%s"', (input, expected) => {
const { document } = new Window({
url: 'http://localhost',
});
const { document } = parseHTML('<html></html>');
const root = '/some/root';
const config = fakeResolvedConfig({
root,
@@ -55,7 +53,7 @@ describe('Dev HTML Prerender Plugin', () => {
const id = root + '/entrypoints/popup/index.html';
document.head.innerHTML = `<link rel="stylesheet" href="${input}" />`;
pointToDevServer(config, server, id, document as any, 'link', 'href');
pointToDevServer(config, server, id, document, 'link', 'href');
const actual = document.querySelector('link')!;
expect(actual.getAttribute('href')).toBe(expected);
@@ -12,7 +12,7 @@ export function bundleAnalysis(config: ResolvedConfig): vite.Plugin {
config.analysis.outputDir,
`${config.analysis.outputName}-${increment++}.json`,
),
});
}) as vite.Plugin;
}
/**
@@ -16,7 +16,7 @@ export function devServerGlobals(
return {
define: {
__DEV_SERVER_ORIGIN__: JSON.stringify(
server.origin.replace(/^http(s):/, 'ws$1:'),
server.origin.replace(/^http(s?):/, 'ws$1:'),
),
},
};

Some files were not shown because too many files have changed in this diff Show More