Compare commits

...

665 Commits

Author SHA1 Message Date
GitHub Actions b98a5c378e chore(release): v0.18.3 2024-05-24 10:51:34 +00:00
Aaron 215def7e15 fix(security): Upgrade tar to 6.2.1 2024-05-24 05:46:11 -05:00
Aaron 3b954cc6fb chore: Upgrade templates to v0.18 2024-05-24 05:40:07 -05:00
Aaron 20bdd8ad2f fix: Remove import * as imports from entrypoints during build (#671) 2024-05-24 05:38:53 -05:00
Edoan cb9a9c0530 docs: Add YTBlock to homepage (#666) 2024-05-21 12:01:55 -05:00
Aaron 48d8d236c0 fix: Automatically add dev server to sandbox CSP (#663) 2024-05-20 23:41:11 -05:00
Aaron 87d9511b31 chore: Add missing tests for dev mode CSP (#662) 2024-05-20 23:35:21 -05:00
Aaron 5d8efef02f ci: Fix sync-releases workflow trigger 2024-05-08 11:04:58 -05:00
Aaron c9008cd835 Update changelog 2024-05-08 11:03:17 -05:00
GitHub Actions 203a9cc234 chore(release): v0.18.2 2024-05-08 15:50:03 +00:00
Aaron 5fcaf7c68b fix: Automatically detect and add "sidePanel" permission 2024-05-08 10:42:07 -05:00
Aaron c74e530d4a docs: Fix iframe typos 2024-05-08 10:34:34 -05:00
Edoan 3f78be0c95 feat(runner): Add keepProfileChanges option (#655) 2024-05-07 22:20:51 -05:00
Linus Norton 2a3d52045d docs: Correct event handler name in handling-updates.md (#653) 2024-05-07 04:31:28 -05:00
Jeffrey Zang ea5b81d25e docs: Fix spelling mistake in remote-code.md (#652) 2024-05-06 21:58:36 -05:00
Emmanuel Ferdman cec9d7103a docs: Fix wxt-vitest-plugin reference (#650)
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
2024-05-05 08:30:40 -05:00
GitHub Actions 34dd2c1487 chore(release): v0.18.1 2024-05-04 16:42:09 +00:00
Aaron a5667f85d0 fix: _background is not defined (#649) 2024-05-04 11:39:29 -05:00
Aaron ec3dd52f83 chore: Add root README back 2024-05-04 11:03:55 -05:00
Aaron 87ebde3abb Fix sync releases workflow 2024-05-04 11:01:08 -05:00
Aaron dc5b55bffb ci: Fix sync releases workflow 2024-05-04 10:59:40 -05:00
Aaron df20993917 Fix changelog generation 2024-05-04 10:57:23 -05:00
Aaron caa0fb31e6 Add breaking change message to changelog 2024-05-04 10:53:35 -05:00
GitHub Actions 95da4fb054 chore(release): v0.18.0 2024-05-04 15:51:44 +00:00
Aaron a917f32a0e feat(experimental): Load entrypoint options with Vite Runtime API (#648) 2024-05-04 10:46:31 -05:00
Aaron 6ca376749c chore: Fix formatting after monorepo refactor 2024-05-04 09:44:07 -05:00
Aaron 792e3032b9 feat: Support returning values from scripts executed with the scripting API (#624) 2024-05-03 17:32:42 -05:00
alegal200 38a5a2c440 docs: Document required permission for storage API (#632)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-05-03 17:28:52 -05:00
yacine-bens 21106ce188 docs: Add MS Edge TTS to homepage (#647) 2024-05-03 17:26:34 -05:00
Aaron ec7263e7de chore: Refactor repo to a standard monorepo (#646) 2024-05-03 17:16:33 -05:00
dependabot[bot] e7c3fc2a5e chore(deps-dev): bump simple-git-hooks from 2.9.0 to 2.11.1 (#640)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 08:14:03 -05:00
dependabot[bot] f808cb7526 chore(deps-dev): bump publint from 0.2.6 to 0.2.7 (#639)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 08:13:15 -05:00
dependabot[bot] c4795e7479 chore(deps): bump react and @types/react (#638)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 08:13:02 -05:00
dependabot[bot] b44a96ab81 chore(deps-dev): bump lint-staged from 15.2.1 to 15.2.2 (#637)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 08:12:45 -05:00
evsamson 3bfdc5c755 FIX: Chromium window-size example format (#630)
Co-authored-by: smsnbv <active.sock7816@fastmail.com>
2024-04-22 07:12:30 -05:00
Aaron acb75543ff docs: Add docs about handling updates
Related to #620
2024-04-20 00:04:05 -05:00
Aaron 25b45b9c09 fix(dep): Upgrade @webext-core/isolated-element to v1.1.2 (#625) 2024-04-19 22:09:16 -05:00
Aaron efd5c40043 fix!: Automatically move host_permissions to permissions for MV2 (#626)
BREAKING CHANGE: Out of an abundance of caution, I've marked this as a breaking change because permission generation has changed. ***If you list `host_permissions` in your `wxt.config.ts`'s manifest and have released your extension***, double check that your `permissions` and `host_permissions` have not changed for all browsers you target. Permission changes can cause the extension to be disabled on update, and can cause a drop in users, so be sure to double check for differences compared to the previous manifest version.
2024-04-19 22:08:52 -05:00
Aaron e47519fb76 docs: Update content script registration JSDoc
See https://github.com/wxt-dev/wxt/discussions/623
2024-04-19 15:59:14 -05:00
Ayden 171e32c272 docs: Add ElemSnap to homepage (#621) 2024-04-19 08:00:41 -05:00
wuzequanyouzi 54e5ed0bb4 chore: Update vue template config (#607)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-04-15 12:43:43 -05:00
Aaron a94d673f31 docs: Fix typo in assets page 2024-04-15 12:17:02 -05:00
yacine-bens b7f7222c26 docs: Add Facebook Video Controls to homepage (#615) 2024-04-15 12:13:06 -05:00
Can Rau aa5a9d4fa9 docs: Tix typo in entrypoints.md (#614) 2024-04-14 17:21:12 -05:00
日高 凌 77da2d6ade docs: Fix typo on example for wxt.config.ts. (#609) 2024-04-12 09:00:15 -05:00
Bas van Zanten 3119c04e10 feat: Add zip compression settings (#605) 2024-04-12 08:59:54 -05:00
couriourc c09994263e doc: Fix bad extension API examples (#608) 2024-04-12 01:01:07 -05:00
ThinkStu 2a4fa9ae5c docs: Add Fluent Read to homepage (#600)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-04-07 09:01:02 -05:00
Aaron c833d3b15b Update test snapshot after vite upgrade 2024-04-07 08:53:15 -05:00
Aaron d6e095bfce Fix type error 2024-04-07 08:47:52 -05:00
Aaron 825160a3cc chore(deps): Upgrade vite 2024-04-03 14:16:51 -05:00
Aaron e29ca33f82 Add missing cleanup from PR 2024-04-03 14:15:55 -05:00
GitHub Actions ca5a52c6f1 chore(release): v0.17.12 2024-04-03 19:04:03 +00:00
Aaron 982c69f8ae feat: Add hooks for extending vite config (#599) 2024-04-03 14:00:48 -05:00
Aaron 6fc7d9254a fix(content-script-ui): Properly assign and unassign mounted value (#598) 2024-04-03 12:38:46 -05:00
dependabot[bot] 2e0e104d48 chore(deps): bump c12 from 1.5.1 to 1.10.0 (#592)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 23:23:11 -05:00
dependabot[bot] 02430fd7b8 chore(deps-dev): bump sass from 1.69.5 to 1.72.0 (#591)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 23:23:01 -05:00
dependabot[bot] 2e6d35d193 chore(deps-dev): bump vue from 3.3.10 to 3.4.21 (#589)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 23:08:37 -05:00
dependabot[bot] 7cf412ac1f chore(deps): bump vitest from 1.2.2 to 1.4.0 (#590)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 22:15:44 -05:00
Aaron 9398cbb596 docs: Add discord server link (#593) 2024-04-01 19:13:12 -05:00
dependabot[bot] ca9b96142e chore(deps-dev): bump @aklinker1/check from 1.1.1 to 1.2.0 (#588)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 18:10:28 -05:00
Aaron db57c8e079 chore: Remove unnecssary 'Omit' types 2024-03-31 08:40:21 -05:00
GitHub Actions 7e37e11caf chore(release): v0.17.11 2024-03-31 13:22:25 +00:00
Aaron bb90029c54 fix: Resolve absolute paths from the public directory properly (#583) 2024-03-31 08:19:06 -05:00
Aaron d3b14afbce chore: Extract helper function 2024-03-30 14:49:10 -05:00
Aaron ba2197a609 chore: Add some array utils (#582) 2024-03-30 13:30:45 -05:00
Aaron 4c558d3eb6 chore: Simplify virtual module setup (#581) 2024-03-30 12:44:27 -05:00
Qiwei Yang dcd175444a docs: Add "GitHub Custom Notifier" to homepage (#580) 2024-03-30 08:37:26 -05:00
Aaron 16fc58404a docs: Fix zip.includeSources example 2024-03-30 08:37:00 -05:00
GitHub Actions 28c7e7d9ed chore(release): v0.17.10 2024-03-29 05:52:30 +00:00
Zizheng Tai 5a3b42a4b0 feat: Add dev.server.port config (#577)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-03-29 00:49:36 -05:00
Aaron c9c5d721ec chore: Refactor order of config resolution (#578) 2024-03-29 00:21:09 -05:00
Aaron 1556b9ad73 chore: Use @aklinker1/check to simplify checks setup (#550) 2024-03-25 15:15:40 -05:00
GitHub Actions ca15b1f321 chore(release): v0.17.9 2024-03-25 06:13:23 +00:00
Aaron 448436cb08 chore: Merge user config using defu (#568) 2024-03-25 01:09:52 -05:00
Aaron c9ddc3d0f2 fix: Don't override wxt.config.ts options when CLI flags are not passed (#567) 2024-03-25 00:24:56 -05:00
Guillaume 6b72f883b6 feat: Add {{mode}} Template Variable (#566)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-03-25 00:01:59 -05:00
GitHub Actions cd3446bd7f chore(release): v0.17.8 2024-03-24 16:26:00 +00:00
Aaron 829b371bba fix(dev): Don't crash dev mode when rebuild fails (#565) 2024-03-24 11:23:16 -05:00
Aaron 36b399dd49 feat(analysis): Open stats.html file automatically (#564) 2024-03-24 11:05:34 -05:00
btea 08f32aa685 chore: Add a test covering wxt init in a non-empty directory (#563)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-03-24 10:15:59 -05:00
Vlad Fedosov 05db264e02 docs: Fixed "Reload the Extension" section (#559)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-03-20 16:52:52 -05:00
btea de5a01834c fix(init): Don't overwrite existing files when initializing a new project (#556)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-03-20 09:22:53 -05:00
Lpmvb 1d260dbacb chore(vue-template): Upgrade to vue-tsc v2 (#549) 2024-03-15 08:08:40 -05:00
Aaron 53c63b4556 chore: Switch to seed plugin for testing (#547) 2024-03-15 00:43:20 -05:00
btea 816878bc15 fix: Append option description error (#546) 2024-03-13 23:07:32 -05:00
Guillaume e087a0d6ef docs: Add examples for GitHub Actions (#540)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-03-13 23:07:17 -05:00
Aaron 56b71491a6 chore: Increase hook timeout for Windows/NPM tests 2024-03-13 12:34:59 -05:00
Aaron 121b521157 docs: Mention adding unlisted scripts and pages to web_accessible_resources
This closes #536
2024-03-12 07:57:38 -05:00
Sunshio 16c2e3218b docs: Add documentation for Bun.sh (#543)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-03-12 07:46:46 -05:00
Aaron d9cba55d34 chore: Increase unit test timeout 2024-03-12 07:45:42 -05:00
Guillaume 832cd5d640 docs: Add Plex skipper to "Using WXT" section (#541) 2024-03-10 09:03:18 -05:00
btea bb95e08d71 docs: Update README demo video (#539) 2024-03-10 09:03:03 -05:00
Aaron 35269dad9e docs: Update homepage demo video
This closes #535
2024-03-09 10:04:23 -06:00
btea 64d1498460 fix: Remove deprecated extension from Vue template (#534) 2024-03-08 21:03:56 -06:00
Luca Dalli 0d540a6df9 docs: Replace pnpx with pnpm dlx (#527) 2024-03-06 16:04:52 -06:00
Aaron b47c150daa fix(init): Better error logging when templates fail to load
This fixes #528
2024-03-06 07:46:26 -06:00
GitHub Actions 38345481df chore(release): v0.17.7 2024-03-04 16:29:56 +00:00
Aaron da92449e0f Undo change to log 2024-03-04 10:26:30 -06:00
Aaron 23b3980645 fix(zip): List .wxt/local_modules overrides relative to the package.json they're added to (#526) 2024-03-04 10:23:18 -06:00
Aaron 81b4b629c9 chore: Increase test timeout for windows NPM tests (#525) 2024-03-04 07:48:39 -06:00
Aaron 4f7e9cb050 chore: Bump templates to v0.17 (#524) 2024-03-04 07:32:18 -06:00
GitHub Actions b226d9b947 chore(release): v0.17.6 2024-03-03 16:05:15 +00:00
Aaron aabba41e86 fix(zip): List all private packages correctly in a PNPM workspace (#520) 2024-03-03 09:56:42 -06:00
Aaron f19e6908b0 feat: Automatically generate browser_action based on action for MV2 (#519) 2024-03-03 09:52:43 -06:00
Aaron 5f651cc3fe feat: Automatically remove top-level MV2-only or MV3-only keys (#518)
When targeting MV2, all MV3 keys will be removed. When targeting MV3, all MV2 keys will be removed.
2024-03-03 09:22:24 -06:00
Aaron 8a6acbaaf2 feat: Add warnings when important directories are missing (#516) 2024-03-02 08:56:20 -06:00
dependabot[bot] 13ab8e4d01 chore(deps-dev): bump @types/react from 18.2.34 to 18.2.61 (#510)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-02 08:55:51 -06:00
dependabot[bot] bd039dcbab chore(deps): bump chokidar from 3.5.3 to 3.6.0 (#511)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-02 08:55:00 -06:00
Aaron Klinker 9cd4e8342b docs: Mentions moving folders into srcDir
Apart of #515
2024-03-02 08:42:31 -06:00
dependabot[bot] c9633cefec chore(deps): bump linkedom from 0.16.1 to 0.16.8 (#513)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-01 17:04:05 -06:00
GitHub Actions 1dd1370ed7 chore(release): v0.17.5 2024-03-01 18:01:15 +00:00
Aaron 9ff90d0acf feat: Download and override private packages for Firefox code review (#507) 2024-03-01 10:17:45 -06:00
Aaron Klinker b754435589 docs: Fix CLI generation 2024-02-29 12:13:28 -06:00
Aaron Klinker 195d2cceaf docs: Add docs about configuring the manifest as a function 2024-02-29 11:39:06 -06:00
Aaron 420d78b638 feat: Expose package management utils under wxt.pm (#502) 2024-02-28 21:38:35 -06:00
btea b35e499355 docs: Fix typos (#503) 2024-02-28 21:36:43 -06:00
Aaron 41c3d6d015 chore: Use JSZip for wxt zip, enabling future features (#501) 2024-02-28 14:57:29 -06:00
GitHub Actions 64610bad41 chore(release): v0.17.4 2024-02-28 18:28:34 +00:00
Aaron 45b7d7c67f fix: Resolve the path to node_modules/wxt correctly (#498) 2024-02-28 12:25:04 -06:00
Aaron 0bb2746869 feat: Add ResolvedConfig.wxtModuleDir, resolving the directory once (#497) 2024-02-28 11:52:46 -06:00
Aaron Klinker f9b0aa45f8 chore: Fix tests after template change 2024-02-28 11:34:15 -06:00
btea 6f6ce33bbd feat: Add basic content script to templates (#495)
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2024-02-28 11:30:53 -06:00
Aaron Klinker e1c6020997 docs: Add testing example for ContentScriptContext
Apart of #491
2024-02-28 11:17:20 -06:00
Aaron Klinker 012bd7e67f docs: Update context usage 2024-02-28 11:16:56 -06:00
Aaron Klinker 35778f70cb docs: Update comparison page 2024-02-28 10:39:47 -06:00
Aaron Klinker cb4f9aa752 docs: Add CRXJS to comparison page 2024-02-28 08:05:39 -06:00
Aaron Klinker f80fb42483 docs: Fix typos 2024-02-28 07:42:22 -06:00
Leo Shklovskii 02c79ca244 docs: Added DocVersionRedirector to "Using WXT" section (#492) 2024-02-27 23:47:10 -06:00
Qiwei Yang 50e8c86ce9 doc: Add markdown sticky ntoes (#488) 2024-02-25 13:37:10 -06:00
GitHub Actions 6fbfc15be7 chore(release): v0.17.3 2024-02-24 16:43:31 +00:00
Aaron c793d3cf6b fix(storage): Revert #478 and run migrations when item is defined and properly wait for migrations before allowing read/writes (#487) 2024-02-24 10:40:03 -06:00
Aaron Klinker b5f4d8cc1b feat(storage): Guarantee storage.getItems returns values in the same order as requested 2024-02-24 08:56:45 -06:00
Aaron Klinker 77e6d1f5a4 fix: Content scripts crash when using storage.defineItem 2024-02-24 08:23:12 -06:00
GitHub Actions 3f149ac4fa chore(release): v0.17.2 2024-02-23 21:49:55 +00:00
Aaron c0dbffaa82 fix: Don't use sub-dependency binaries directly (#482) 2024-02-23 15:45:18 -06:00
Aaron Klinker 707f03a3eb Update changelog 2024-02-23 12:55:55 -06:00
GitHub Actions 8372462041 chore(release): v0.17.1 2024-02-23 18:54:07 +00:00
Aaron Klinker 3fbbe2ccde fix: Content scripts not loading in dev mode 2024-02-23 12:51:11 -06:00
Leo Shklovskii e7880fcde0 docs: Lots of small typo fixes (#480) 2024-02-23 11:45:58 -06:00
Aaron Klinker ee5e76e4b1 Update changelog 2024-02-22 14:24:38 -06:00
GitHub Actions 1ae8d6bc46 chore(release): v0.17.0 2024-02-22 17:55:31 +00:00
Aaron de7dd09f60 fix: Improve dev mode for content scripts registered at runtime (#474) 2024-02-22 11:52:37 -06:00
Aaron 1649785826 fix(storage)!: Only run migrations when the extension is updated (#478) 2024-02-22 11:46:59 -06:00
Aaron Klinker 91fc41cb15 docs(storage): Update docs 2024-02-22 11:46:59 -06:00
Aaron 9c80ad832b feat(storage)!: Improved support for default values on storage items (#477) 2024-02-22 11:46:48 -06:00
Aaron Klinker 86b7162d99 Update changelog 2024-02-21 08:24:26 -06:00
Aaron Klinker b8f8acd33d Fix typo 2024-02-21 08:24:09 -06:00
GitHub Actions d8905d23a4 chore(release): v0.16.11 2024-02-21 14:17:40 +00:00
Aaron 5d2d124e5a fix: Output main JS file for HTML entrypoints to chunks directory (#473) 2024-02-21 08:13:43 -06:00
Aaron Klinker 4fda203def chore(e2e): Remove log 2024-02-21 08:13:21 -06:00
Aaron Klinker 905bfc7a38 ci: Upgrade pnpm/action-setup to v2 2024-02-20 14:35:53 -06:00
Aaron Klinker 7c6973f0e6 ci: Fix codecov warning in release workflow 2024-02-20 14:35:08 -06:00
GitHub Actions 969e39c541 chore(release): v0.16.10 2024-02-20 20:33:12 +00:00
Aaron b256939cc4 fix: Respect configFile option (#472) 2024-02-20 14:30:21 -06:00
Aaron c46137644b feat: Customize when content scripts are registered, in the manifest or at runtime (#471) 2024-02-20 14:18:53 -06:00
Aaron 1bd7ef56c4 fix: Don't assume react when importing JSX entrypoints during build (#470) 2024-02-20 13:53:00 -06:00
Aaron Klinker c258b99cec Update changelog 2024-02-20 08:26:02 -06:00
GitHub Actions d3abb32cb4 chore(release): v0.16.9 2024-02-20 14:17:52 +00:00
Aaron 223ede9ff9 feat: Support setting side panel options in HTML file (#468) 2024-02-20 08:14:34 -06:00
Aaron 9d31a4eba1 chore: Simplify entrypoint types (#464) 2024-02-19 16:17:54 -06:00
okou ea0e40c269 fix: Fix order of ShadowRootUI hooks calling (#459) 2024-02-19 07:45:57 -06:00
Aaron Klinker bc24ea45a4 docs: Add wrapper div to react's createShadowRootUi example
Related to #456.
2024-02-17 09:20:35 -06:00
GitHub Actions 86d0c9b397 chore(release): v0.16.8 2024-02-15 21:41:43 +00:00
Aaron c275ccf0da fix: Watch files outside project root during development (#454) 2024-02-15 14:23:32 -06:00
Aaron Klinker 447a48f306 docs: Add loading and error states for "Who's using WXT" section 2024-02-15 10:37:58 -06:00
GitHub Actions 70b5cbc8db chore(release): v0.16.7 2024-02-15 16:35:13 +00:00
Aaron 3459de0375 perf: Upgrade Vite to 5.1 (#452) 2024-02-15 10:31:20 -06:00
Aaron c6817479bd feat: Generate ESLint globals file for auto-imports (#450) 2024-02-15 10:14:57 -06:00
Aaron f02aae21f6 chore(e2e): Use wxt prepare instead of wxt build when possible to speed up E2E tests (#451) 2024-02-15 09:59:36 -06:00
Aaron Klinker 87a62a1791 docs: Remove anchor from content script ui examples 2024-02-14 14:43:34 -06:00
Aaron Klinker a0d1643021 docs: Add section about dev mode differences 2024-02-14 14:41:40 -06:00
William Gérald Blondel 856a946fa7 Fix typo on homepage hero section (#438) 2024-02-11 10:13:17 -06:00
GitHub Actions 9d97164c20 chore(release): v0.16.6 2024-02-10 10:29:52 +00:00
lionelhorn 6d526e7043 feat: Add option to customize the analysis artifacts output (#431)
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2024-02-10 04:26:33 -06:00
Aaron Klinker 946072fc5a docs: Fix createShadowRootUi unmount calls 2024-02-10 04:04:16 -06:00
Aaron Klinker 6b8dfdf02d chore: Enable skipped test since it works now 2024-02-10 03:01:38 -06:00
okou ba85fdf470 fix: Use insertBefore on mounting content script UI 2024-02-10 03:01:38 -06:00
okou 295f8601e3 refactor: Use Element.prepend on mounting UI 2024-02-10 03:01:38 -06:00
Aaron a38ccd8624 doc: Fix custom block 2024-02-09 05:20:51 -06:00
GitHub Actions b2dcec2f8a chore(release): v0.16.5 2024-02-09 06:01:00 +00:00
Aaron Klinker e8355029d9 fix: Support node 20 when running wxt submit 2024-02-08 23:55:53 -06:00
Aaron Klinker 2b374b98d2 docs: Remove "coming soon" from automated publishing feature 2024-02-05 23:36:13 -06:00
GitHub Actions d14d76a0c8 chore(release): v0.16.4 2024-02-06 05:21:00 +00:00
Aaron Klinker d0f1c7065c chore: Fix fake path in test data generator 2024-02-05 23:17:14 -06:00
Aaron 3edb66d76d feat: Add option to customize the analysis output filename (#426) 2024-02-05 23:15:15 -06:00
Aaron bba8cdace1 fix: Exclude analysis files from the build summary (#425) 2024-02-05 23:09:30 -06:00
Aaron 22f82a67ee feat: Automatically convert MV3 web_accessible_resources to MV2 (#423) 2024-02-05 22:49:18 -06:00
Aaron b32c60ca73 fix: Don't use immer for transformManifest (#424) 2024-02-05 22:37:26 -06:00
Aaron Klinker c93620cba5 Update changelog 2024-02-04 17:48:26 -06:00
GitHub Actions dd05ed4d4c chore(release): v0.16.3 2024-02-04 23:41:38 +00:00
Aaron 21636defda feat: Hooks (#419)
Deprecated `transformManifest` since a hook now exists for it.
2024-02-04 17:37:31 -06:00
Aaron bb022646e3 chore: Register global wxt instance (#418) 2024-02-04 16:34:10 -06:00
Aaron Klinker 37ad2c7ceb fix(init): Use ungh to prevent rate limits when loading templates 2024-02-04 14:11:41 -06:00
dependabot[bot] b992631e00 chore(deps): bump rollup-plugin-visualizer from 5.9.3 to 5.12.0 (#412)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-04 03:14:47 -06:00
dependabot[bot] 35a5cc6717 chore(deps-dev): bump typescript from 5.3.2 to 5.3.3 (#409)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-04 03:14:15 -06:00
dependabot[bot] 310b56fe5d chore(deps): bump defu from 6.1.3 to 6.1.4 (#413)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-04 03:13:28 -06:00
dependabot[bot] 148234382e chore(deps): bump @types/webextension-polyfill from 0.10.5 to 0.10.7 (#410)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-04 03:13:03 -06:00
dependabot[bot] c1a97b77b0 chore(deps): bump actions/checkout from 3 to 4 (#407)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-04 03:11:32 -06:00
Chen Hua 557ccb4854 docs: fix typo of opinionated (#416) 2024-02-04 03:11:03 -06:00
Chen Hua 83e7e8aab9 docs: Fix typo of intuitive (#415) 2024-02-04 03:10:20 -06:00
dependabot[bot] 7bf490c59d chore(deps-dev): bump happy-dom from 12.10.3 to 13.3.8 (#411)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-04 03:08:24 -06:00
dependabot[bot] 9670babdbb chore(deps): bump codecov/codecov-action from 3 to 4 (#408)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-04 03:06:11 -06:00
Florian Metz 42dfc2d5cf chore: Add dependabot for github actions (#404) 2024-02-03 16:32:46 -06:00
GitHub Actions 1527f0e275 chore(release): v0.16.2 2024-02-03 21:02:28 +00:00
Aaron 66bd957ee0 fix: Don't crash background service worker when using import.meta.url (#402) 2024-02-03 14:57:34 -06:00
GitHub Actions 72e3c5baa2 chore(release): v0.16.1 2024-02-03 19:57:51 +00:00
Aaron Klinker 9318346ab3 fix: Don't require config to run wxt submit init 2024-02-03 13:52:15 -06:00
Aaron Klinker 1d6aceab0a Update changelog 2024-02-03 11:05:16 -06:00
Florian Metz c1b5a9d270 docs: Add premid extension to homepage (#399) 2024-02-02 22:46:46 -06:00
Aaron Klinker f0b2a12724 chore(templates): Upgrade to wxt ^0.16.0 2024-02-02 16:20:24 -06:00
Aaron Klinker c45677ed48 Update changelog 2024-02-02 16:19:33 -06:00
GitHub Actions 7a3f075e21 chore(release): v0.16.0 2024-02-02 16:55:11 +00:00
Aaron Klinker 1e12ce2a0d docs: Document how to opt into ESM 2024-02-02 10:48:00 -06:00
Aaron eca30296a7 feat!: ESM background support (#398)
BREAKING CHANGE: The build output has changed slightly. This isn't a huge deal, and no steps are required for users unless you're doing something weird with the output files after a build.

Before:

```
.output/
  <target>/
    chunks/
      popup-<hash>.js
    popup.html
```

After:

```
.output/
  <target>/
    popup.html
    popup.js
```

This applies for all HTML files, not just the popup.
2024-02-02 10:17:43 -06:00
dependabot[bot] 41fa320815 chore(deps-dev): bump @vitest/coverage-v8 from 1.0.1 to 1.2.2 (#397)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-02 07:07:50 -06:00
dependabot[bot] 873c24fa50 chore(deps-dev): bump p-map from 7.0.0 to 7.0.1 (#396)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-02 07:06:51 -06:00
dependabot[bot] d92db5ba8f chore(deps-dev): bump lint-staged from 15.2.0 to 15.2.1 (#395)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-02 07:06:31 -06:00
dependabot[bot] 1a6fe33f97 chore(deps): bump fast-glob from 3.3.1 to 3.3.2 (#394)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-02 07:05:42 -06:00
GitHub Actions 2db4ea77a9 chore(release): v0.15.4 2024-01-31 17:42:07 +00:00
Aaron ba5349ccaf fix(submit): Load .env.submit automatically when running wxt submit and wxt submit init (#391) 2024-01-31 11:38:11 -06:00
GitHub Actions addb689de9 chore(release): v0.15.3 2024-01-31 14:59:26 +00:00
Aaron 2af8d28b82 fix(dev): Reload <name>/index.html entrypoints properly on save (#390) 2024-01-31 08:50:23 -06:00
Aaron Klinker ddbc66813e Update changelog 2024-01-30 13:04:32 -06:00
GitHub Actions 0c8fc013a8 chore(release): v0.15.2 2024-01-30 19:01:54 +00:00
Aaron 26e30aaae9 feat: Add submit command (#370) 2024-01-30 12:55:17 -06:00
Nenad Novaković 6557dfe430 fix(dev): Resolve script and link aliases (#387)
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2024-01-30 12:05:31 -06:00
Aaron Klinker 9cee9eefb4 Update changelog 2024-01-29 14:12:27 -06:00
GitHub Actions f9cd7aaf05 chore(release): v0.15.1 2024-01-29 20:10:18 +00:00
0x7a7a 9049804413 docs: Fixed doc errors on the guide/extension-api page (#383)
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2024-01-29 14:06:27 -06:00
Aaron d027a496f5 Upgrade wxt init templates to v0.15 (#385) 2024-01-29 14:04:58 -06:00
Aaron dd7abddb7c feat: Allow passing custom preferences to chrome, enabling dev mode on chrome://extensions and allowing content script sourcemaps automatically (#384) 2024-01-29 13:58:46 -06:00
Aaron Klinker 98d2792e02 chore: Fix vite version conflicts in demo extension 2024-01-29 13:53:57 -06:00
Aaron Klinker 39b76d3ec0 fix(security): Upgrade to vite@5.0.12 to resolve CVE-2024-23331 2024-01-29 11:25:31 -06:00
Aaron Klinker bc29bfd434 Update changelog 2024-01-29 11:22:41 -06:00
GitHub Actions 5e60f37ec5 chore(release): v0.15.0 2024-01-29 17:18:38 +00:00
Aaron 6f901b32eb fix: Enable inline sourcemaps by default during development (#382) 2024-01-29 11:15:57 -06:00
Aaron 927aca612e fix!: Move browser constants to import.meta.env (#380)
BREAKING CHANGE: Renamed undocumented constants:

- `__BROWSER__` &rarr; `import.meta.env.BROWSER`
- `__COMMAND__` &rarr; `import.meta.env.COMMAND`
- `__MANIFEST_VERSION__` &rarr; `import.meta.env.MANIFEST_VERSION`
- `__IS_CHROME__` &rarr; `import.meta.env.CHROME`
- `__IS_FIREFOX__` &rarr; `import.meta.env.FIREFOX`
- `__IS_SAFARI__` &rarr; `import.meta.env.SAFARI`
- `__IS_EDGE__` &rarr; `import.meta.env.EDGE`
- `__IS_OPERA__` &rarr; `import.meta.env.OPERA`
2024-01-29 11:14:18 -06:00
Nenad Novaković 2dcdae91eb feat(zip)!: add includeSources and rename ignoredSources to excludeSources (#378)
Co-authored-by: Aaron <aaronklinker1@gmail.com>

BREAKING CHANGE: Renamed `ignoredSources` to `excludeSources`
2024-01-29 11:13:39 -06:00
Aaron Klinker eb758bdeb8 chore: Update contributor docs
See https://github.com/wxt-dev/wxt/pull/378\#issuecomment-1915064721
2024-01-29 10:59:54 -06:00
Aaron 5acf51af9d fix: Generate missing sourcemap in wxt:unimport plugin (#381) 2024-01-29 10:30:42 -06:00
Aaron Klinker f9718a1b71 docs: Fix typo 2024-01-28 09:42:45 -06:00
GitHub Actions cf7f23d4c3 chore(release): v0.14.7 2024-01-27 17:31:33 +00:00
Aaron Klinker 62ecb6f41e fix: Upgrade web-ext-run
This closes #324
2024-01-27 11:25:49 -06:00
Aaron Klinker fc45c37f22 docs: Add missing await to createShadowRootUi examples
This closes #374
2024-01-27 11:02:15 -06:00
Aaron Klinker 68874e607e docs: Document defined constants for the build target 2024-01-27 10:56:14 -06:00
Aaron Klinker 35865adcb2 fix(storage): Throw better error message when importing outside a extension environment
This closes #371
2024-01-27 00:26:35 -06:00
Aaron Klinker 3b63a51475 fix: Improve error messages when importing and building entrypoints 2024-01-27 00:20:48 -06:00
東奈比 d32e59e38f docs: fix incorrect sample code (#372) 2024-01-26 10:26:10 -06:00
Aaron Klinker dab8efa140 docs: Add matches to content script examples 2024-01-24 07:58:47 -06:00
GitHub Actions c298d8552b chore(release): v0.14.6 2024-01-24 06:34:25 +00:00
Aaron 87267347f3 feat: Add basic validation for entrypoint options (#368) 2024-01-24 00:31:05 -06:00
Aaron 326e84b667 feat: Restart dev mode when saving config (#365) 2024-01-19 22:58:49 -06:00
Aaron Klinker 4b005b450e ci: Check for type errors in demo before building 2024-01-19 22:57:06 -06:00
Aaron 3bf40fc4ed fix: Sort build output files naturally (#364) 2024-01-19 11:35:09 -06:00
Aaron 9ace395e11 fix: Add subdependency bin directory so wxt build --analyze works with PNPM (#363) 2024-01-19 11:32:18 -06:00
GitHub Actions 64f42064ae chore(release): v0.14.5 2024-01-19 14:36:07 +00:00
Aaron a525d786f1 feat: Add dev.reloadCommand config (#362) 2024-01-19 08:33:03 -06:00
Aaron 948ee810da fix: Disable reload dev command when 4 commands are already registered (#361) 2024-01-19 07:47:04 -06:00
GitHub Actions 8687b2980e chore(release): v0.14.4 2024-01-18 20:54:29 +00:00
Aaron 6f0814bc97 fix: Allow requiring built-in node modules from ESM CLI (#356) 2024-01-18 14:51:35 -06:00
Aaron 148c0da51f chore: Add unit tests for passing flags via the CLI (#354) 2024-01-18 14:49:35 -06:00
GitHub Actions ba09f3e0f1 chore(release): v0.14.3 2024-01-17 05:20:19 +00:00
Yuns 54e24652da fix: Make getArrayFromFlags result can be undefined (#352) 2024-01-16 23:15:18 -06:00
GitHub Actions d6516142d2 chore(release): v0.14.2 2024-01-16 19:57:03 +00:00
Yuns 460667e3c0 feat: Add filterEntrypoints option to speed up development (#344)
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2024-01-16 13:52:58 -06:00
Armin 6ed61d0766 docs: Fix typos and outdated ui function usage (#347) 2024-01-16 13:01:12 -06:00
Aaron 971daf2784 fix: Allow browser.runtime.getURL to include hashes and query params for HTML paths (#350) 2024-01-16 12:59:38 -06:00
Aaron 89d8ef9a50 fix: Improve error message and document use of imported variables outside an entrypoint's main function (#346) 2024-01-14 09:36:22 -06:00
Aaron Klinker a329e24818 chore: Fix typo in function name 2024-01-12 13:03:43 -06:00
Aaron 249cf63da8 perf: Only call findEntrypoint once per build (#342) 2024-01-12 13:02:44 -06:00
Aaron Klinker 70a496108a chore: Update templates to ^0.14.0 2024-01-12 08:53:32 -06:00
GitHub Actions 214889e052 chore(release): v0.14.1 2024-01-12 14:50:29 +00:00
Aaron Klinker b6ab7a9567 fix: Use Alt+R/Opt+R to reload extension during development
This closes #339
2024-01-12 08:47:21 -06:00
Aaron Klinker 1ceb9e2e80 Add missing breaking change to changelog 2024-01-11 17:00:43 -06:00
Aaron Klinker 15ea81514f Update changelog 2024-01-11 13:28:41 -06:00
GitHub Actions 21d4e6dede chore(release): v0.14.0 2024-01-11 17:17:23 +00:00
Aaron 5343430c0f feat!: Refactor content script UI functions and add helper for "integrated" UIs (#333)
BREAKING CHANGES: Several APIs/options have been renamed:

- `type: "inline" | "overlay" | "modal"` has been changed to `position: "inline" | "overlay" | "modal"`
- `createContentScriptUi({ ... })` &rarr; `createShadowRootUi({ ... })`
- `createContentScriptIframe({ ... })` &rarr; `createIframeUi({ ... })`
- `onRemove` is now called ***before*** the UI is removed from the DOM, previously it was called after the UI was removed
2024-01-10 20:48:17 -06:00
GitHub Actions 8c834835c4 chore(release): v0.13.5 2024-01-08 20:10:48 +00:00
Aaron 9a2cc18f64 chore: Update bug report template 2024-01-08 13:50:20 -06:00
Aaron Klinker 8683bd4b77 docs: Add section about customizing other browser options during development 2024-01-08 13:42:50 -06:00
Aaron dca52864bb fix: Strip path from web_accessible_resources[0].matches (#332) 2024-01-08 13:17:31 -06:00
GitHub Actions 0c5643f648 chore(release): v0.13.4 2024-01-07 16:51:31 +00:00
Aaron Klinker b7cdf1597c fix: Disable minification during development
This closes #328
2024-01-07 10:48:25 -06:00
Aaron Klinker 2770974261 chore: Use const instead of let 2024-01-07 10:46:49 -06:00
GitHub Actions ab6a34afb6 chore(release): v0.13.3 2024-01-05 05:14:03 +00:00
Aaron b0eb7da9b4 chore: Refactor manifest generation E2E tests to unit tests (#323) 2024-01-02 17:05:23 -06:00
Aaron 4f649fc872 feat(DX): Add ctrl+E/cmd+E shortcut to reload extension during development (#322) 2024-01-02 12:06:22 -06:00
dependabot[bot] 1af64aa02f chore(deps-dev): bump vitepress from 1.0.0-rc.31 to 1.0.0-rc.34 (#316)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-01 14:33:18 -06:00
dependabot[bot] c35acff259 chore(deps-dev): bump prettier from 3.1.0 to 3.1.1 (#318)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-01 14:31:32 -06:00
dependabot[bot] 995d4f8080 chore(deps-dev): bump tsx from 4.6.2 to 4.7.0 (#320)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-01 14:31:16 -06:00
GitHub Actions b7e2aa3d8f chore(release): v0.13.2 2024-01-01 16:06:12 +00:00
冯不游 e347f4529f feat: Add isolateEvents option to createContentScripUi (#313)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-01-01 10:01:33 -06:00
李志博 3d9683418d Upload a Chinese dubbing plugin for Youtube. (#314)
Co-authored-by: Aaron <aaronklinker1@gmail.com>
2024-01-01 09:45:44 -06:00
Aaron bdce363eed chore: Re-enable coverage (#312) 2023-12-29 17:28:35 -06:00
Aaron e7775f291a docs: Use example tags to automate relevant example lists (#311) 2023-12-29 17:25:46 -06:00
Aaron 59f6a28c65 chore: Upgrade template dependencies (#310) 2023-12-29 12:25:13 -06:00
Aaron f7534464bc chore: Update templates to ^0.13.0 (#309) 2023-12-29 12:14:05 -06:00
Aaron 01445fb1da docs: Add example for setting up custom panels/panes in devtools (#308) 2023-12-29 12:08:33 -06:00
Aaron Klinker 1360eb7c01 docs: Update content script entrypoint docs 2023-12-29 02:01:53 -06:00
Aaron Klinker c99a281169 docs: Update unlisted pages/scripts description 2023-12-29 01:54:39 -06:00
Aaron Klinker 76e63e24c0 docs: Remove duplicate entrypoints/ path 2023-12-29 01:51:26 -06:00
GitHub Actions f5ba1173da chore(release): v0.13.1 2023-12-29 07:39:32 +00:00
Aaron 12079e6ffc chore: Update scripts/build.ts show current build step in progress, not completed count (#306) 2023-12-29 01:21:18 -06:00
Aaron ff6740d429 fix: Ship vite/client types internally for proper resolution using PNPM (#304) 2023-12-29 01:21:05 -06:00
Aaron e6657cb533 fix(storage): Support multiple : characters in storage keys (#303) 2023-12-29 00:40:47 -06:00
Aaron Klinker 2ad099bf7e docs: General fixes and improvements 2023-12-27 12:32:59 -06:00
Aaron Klinker 6421ab34a4 docs: Reorder guide 2023-12-27 12:32:45 -06:00
Aaron Klinker 8919c4015a Update changelog 2023-12-27 11:07:57 -06:00
GitHub Actions 712f2ed4ac chore(release): v0.13.0 2023-12-27 17:05:45 +00:00
Aaron d1b9e5ded6 feat!: New wxt/storage APIs (#300)
BREAKING CHANGE: `wxt/storage` no longer relies on `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.
2023-12-27 11:00:10 -06:00
GitHub Actions 86182044d1 chore(release): v0.12.5 2023-12-24 14:28:21 +00:00
Aaron e1f181356c fix: Correct import in dev-only, noop background (#298) 2023-12-24 08:24:53 -06:00
GitHub Actions 5f241cf407 chore(release): v0.12.4 2023-12-23 15:53:43 +00:00
Aaron b4a2cf4cb2 fix: Disable Vite CJS warnings (#296) 2023-12-23 09:35:43 -06:00
GitHub Actions aea137a3a1 chore(release): v0.12.3 2023-12-23 04:26:47 +00:00
Aaron ad0e8e4144 fix: Correctly mock webextension-polyfill for Vitest (#294) 2023-12-22 22:21:09 -06:00
GitHub Actions 7fd5752ef1 chore(release): v0.12.2 2023-12-19 17:48:24 +00:00
Aaron 1a8b7ff635 feat: Support PNPM without hoisting dependencies (#291) 2023-12-19 11:42:20 -06:00
GitHub Actions fe3ca0fcbd chore(release): v0.12.1 2023-12-16 17:24:16 +00:00
Aaron f49ee9f005 fix: Fix package.json lint errors (#290) 2023-12-16 11:18:16 -06:00
Aaron 961440c0ac fix: Upgrade @webext-core/match-patterns to 1.0.3 (#289) 2023-12-16 11:07:18 -06:00
Aaron 9b562b0ca8 chore: Upgrade templates to wxt@^0.12.0 (#285) 2023-12-13 16:21:52 -06:00
Aaron Klinker 7b2563b2dc Update changelog with breaking changes 2023-12-13 16:02:24 -06:00
GitHub Actions 63f507ecf5 chore(release): v0.12.0 2023-12-13 21:57:34 +00:00
Aaron 0a88955394 fix: Throw error when no entrypoints are found (#283) 2023-12-13 15:50:28 -06:00
Aaron Klinker 291d25b675 docs: Fix dead links 2023-12-13 15:50:09 -06:00
Aaron 6f902cc598 docs: Improve content script UI guide (#272) 2023-12-13 15:43:40 -06:00
Aaron fde488ac82 feat!: Add support for "main world" content scripts (#284)
BREAKING CHANGE: `defineContentScript` and `defineBackground` are now exported from `wxt/sandbox` instead of `wxt/client`. If you use auto-imports, no changes are required. If you have disabled auto-imports, you'll need to manually update your import statements.
2023-12-13 15:41:39 -06:00
Aaron 0873c24ad8 chore: Convert WXT CLI to an ESM binary (#279) 2023-12-12 14:44:04 -06:00
Aaron 7c02497148 fix: Only use type imports for Vite (#278) 2023-12-12 14:24:42 -06:00
GitHub Actions 25441a3b97 chore(release): v0.11.2 2023-12-12 19:24:47 +00:00
Aaron f1cf866fe1 fix: Improve duplicate entrypoint name detection and catch the error before loading their config (#276) 2023-12-12 13:22:09 -06:00
Aaron d92a126489 fix: Discover .js, .jsx, and .tsx unlisted scripts correctly (#274) 2023-12-12 12:24:38 -06:00
Aaron Klinker bcb93afe4e chore: Add missing navigation item 2023-12-09 23:37:29 -06:00
Aaron 21cf3642cb docs: Improve content script UI docs (#268) 2023-12-09 23:36:35 -06:00
Andrew Walsh 2ef28ec0c4 Update content-scripts.md (#266) 2023-12-09 23:33:59 -06:00
Aaron 59094c9af3 chore: Update sSolid template to vite 5 (#265) 2023-12-07 23:05:08 -06:00
GitHub Actions ba41691296 chore(release): v0.11.1 2023-12-07 21:41:45 +00:00
Aaron 8786aa91b3 feat: Add util for detecting URL changes in content scripts (#264) 2023-12-07 13:29:33 -06:00
Aaron 0623d10653 chore: Upgrade templates to wxt@^0.11.0 (#263) 2023-12-06 11:39:03 -06:00
Aaron Klinker 85174d4994 Fix changelog 2023-12-06 11:33:49 -06:00
GitHub Actions 4e2dd5d618 chore(release): v0.11.0 2023-12-06 17:24:11 +00:00
Aaron 1a39a0d153 feat!: Vite 5 support (#261) 2023-12-06 11:18:52 -06:00
Aaron f922648dd7 chore: Abstract vite from WXT's core logic (#242) 2023-12-05 16:55:22 -06:00
Ítalo Brasil e6142e3608 docs: Adds tl;dv to homepage (#260) 2023-12-05 12:30:57 -06:00
Aaron ed73451fd0 chore: Speed up CI using pnpm instead of npm (#259) 2023-12-04 14:14:44 -06:00
GitHub Actions 8a25a2f60f chore(release): v0.10.4 2023-12-04 15:54:42 +00:00
Aaron 397e9a8b45 feat: Add config to customize outDir (#258) 2023-12-04 09:50:24 -06:00
dependabot[bot] 7cef7680de chore(deps): bump esbuild from 0.19.5 to 0.19.8 (#253)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-01 15:23:31 -06:00
dependabot[bot] 0c57375758 chore(deps-dev): bump tsx from 3.14.0 to 4.6.1 (#252)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-01 15:09:19 -06:00
dependabot[bot] 2c6af84165 chore(deps): bump rollup-plugin-visualizer from 5.9.2 to 5.9.3 (#256)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-01 15:08:06 -06:00
dependabot[bot] 58e1371701 chore(deps-dev): bump @types/lodash.merge from 4.6.8 to 4.6.9 (#255)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-01 15:06:58 -06:00
dependabot[bot] 0d8e7463b8 chore(deps-dev): bump prettier from 3.0.3 to 3.1.0 (#254)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-01 15:06:24 -06:00
Aaron 77eeacaf0f docs: Update sidepanel availability (#250) 2023-11-29 17:12:37 -06:00
冯不游 e80c134150 docs: Add Doozy to homepage (#249) 2023-11-29 07:21:46 -06:00
GitHub Actions 03c8ab4d6f chore(release): v0.10.3 2023-11-28 18:18:59 +00:00
Aaron df13b9705c fix(auto-imports): Don't add imports to node_module dependencies (#247) 2023-11-28 12:15:05 -06:00
Aaron 762ba0080d chore(deps): Upgrade to typescript 5.3 (#245) 2023-11-27 10:03:03 -06:00
Aaron Klinker 317b1b6dcc docs: Fix typo 2023-11-27 09:57:09 -06:00
Aaron 93175a6477 chore: Use defu for merging some config objects (#243) 2023-11-26 12:23:10 -06:00
Aaron 60d6707b11 chore: Use normalize-path instead of vite.normalizePath (#244) 2023-11-26 11:36:42 -06:00
Aaron Klinker 97cbda3dab ci: only print response headers from docs webhook 2023-11-25 14:57:04 -06:00
Aaron Klinker 1611c1dba6 ci: Publish docs on push to main 2023-11-25 14:51:30 -06:00
Aaron Klinker b59252284a Print verbose webhook 2023-11-25 14:48:05 -06:00
Aaron Klinker 742b99657a chore: Trigger docs upgrade via webhook 2023-11-25 14:45:41 -06:00
Aaron Klinker e2997a43e0 Fix docker push command 2023-11-24 14:18:27 -06:00
Aaron Klinker 21dead60fd Self-host docs 2023-11-24 14:16:18 -06:00
GitHub Actions 3d1bc0a12c chore(release): v0.10.2 2023-11-20 19:52:55 +00:00
Aaron Klinker 4b24bee1fb Update demo app logs 2023-11-20 13:47:31 -06:00
Aaron Klinker 82ed821eb5 fix: Apply mode option to build steps correctly 2023-11-20 13:47:18 -06:00
Aaron 60625280c2 chore: Upgrade templates to v0.10 (#239) 2023-11-16 16:50:30 -06:00
GitHub Actions 083792b5f0 chore(release): v0.10.1 2023-11-16 17:46:36 +00:00
Aaron Klinker 3da3e07bda fix: Remove WXT global to remove unused modules from production builds 2023-11-16 11:35:20 -06:00
Aaron Klinker 64d61eb3f1 Update changelog 2023-11-14 23:26:27 -06:00
GitHub Actions aa6009e476 chore(release): v0.10.0 2023-11-15 05:21:53 +00:00
Aaron d2cb8f9416 feat: Add wxt/storage API (#234) 2023-11-14 23:07:45 -06:00
Nenad Novaković 046a4809d3 feat!: Allow plural directory and only png's for manifest icons (#237)
BREAKING CHANGE: No longer discover icons with extensions other than `.png`. If you previously used `.jpg`, `.jpeg`, `.bmp`, or `.svg`, you'll need to convert your icons to `.png` files or manually add them to the manifest inside your `wxt.config.ts` file.
2023-11-14 23:07:09 -06:00
Aaron Klinker 207b750d4e docs: Update main README links 2023-11-12 10:37:56 -06:00
Aaron 077fa9939e feat: List bun as an experimental option in wxt init (#233) 2023-11-11 15:45:29 -06:00
Aaron 44d715a29e fix: Don't use bun to load entrypoint config (#232) 2023-11-11 14:46:13 -06:00
GitHub Actions 3ab9fe4ae3 chore(release): v0.9.2 2023-11-11 19:57:25 +00:00
Aaron 91b28c2cb9 feat: Experimental option to exclude webextension-polyfill (#231) 2023-11-11 13:53:47 -06:00
Aaron Klinker d1b523061f ci: Fix sync-release workflow 2023-11-11 12:49:40 -06:00
Aaron Klinker c69ea3967f Fix changelog 2023-11-11 12:47:32 -06:00
GitHub Actions 41527a2200 chore(release): v0.9.1 2023-11-11 18:27:09 +00:00
Aaron 281f28192d fix: Generate valid manifest for Firefox MV3 (#229) 2023-11-11 12:22:46 -06:00
Aaron 67ffa44f9c docs: Update feature comparison 2023-11-11 08:53:59 -06:00
Aaron Klinker 421c0e412d docs: Add StayFree to homepage (#221) 2023-11-08 10:51:42 -06:00
Aaron d21ee08eb6 docs: Add UltraWideo to homepage (#193) 2023-11-08 09:26:51 -06:00
Aaron 7fa150dfae docs: Improve the "Used By" section on homepage (#220) 2023-11-08 08:27:58 -06:00
Aaron 7ba52b18fd ci: Automatically sync GitHub releases with CHANGELOG.md on push (#218) 2023-11-07 13:08:46 -06:00
Aaron 66e5079b84 feat: Add alias config for customizing path aliases (#216) 2023-11-07 11:38:48 -06:00
Aaron Klinker f1e8084be8 chore: Update Vite dependency range to ^4.0.0 || ^5.0.0-0 2023-11-07 10:42:36 -06:00
Aaron Klinker 609ae2ae37 fix: Move webextension-polyfill from peer to regular dependencies
This closes https://github.com/wxt-dev/wxt/issues/215
2023-11-07 10:38:24 -06:00
Aaron Klinker c81dfff37c docs: Add examples 2023-11-05 11:35:59 -06:00
Aaron 9c27820add chore: Upgrade templates to wxt@^0.9.0 (#214) 2023-11-04 13:01:05 -05:00
Aaron 22f8e10918 chore: Remove whitespace from genearted .wxt files (#211) 2023-11-04 12:28:31 -05:00
Aaron Klinker 96d41f8b7c Update changelog 2023-11-04 11:17:32 -05:00
GitHub Actions c4ce44e001 chore(release): v0.9.0 2023-11-04 15:56:43 +00:00
yyyanghj 6641ffaeed fix!: Remove lib from .wxt/tsconfig.json (#209)
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2023-11-04 10:50:52 -05:00
Aaron 450dc0975f Add CLI screenshot back to README 2023-11-04 09:12:06 -05:00
Aaron d343555f41 Update MP4 title 2023-11-04 01:34:25 -05:00
Aaron 7993908c6c docs: Add demo video (#208) 2023-11-04 01:32:19 -05:00
yyyanghj 94e1dbce24 chore: Fix Svelte and React template READMEs (#207) 2023-11-03 12:59:35 -05:00
Aaron d14215946a Cleanup README badge links 2023-11-03 11:46:14 -05:00
Aaron Klinker 345406f02a docs: Fix heading 2023-11-03 09:39:09 -05:00
GitHub Actions 6b689bab23 chore(release): v0.8.7 2023-11-03 14:36:36 +00:00
Aaron fcdf0dcbe9 feat: createContentScriptIframe utility (#206) 2023-11-03 09:31:16 -05:00
Aaron bd35acdae1 chore: Run E2E tests in parallel (#204) 2023-11-02 11:15:07 -05:00
Aaron 21c35ee593 ci: Separate validation into multiple jobs (#203) 2023-11-02 11:08:19 -05:00
Aaron Klinker 0f09cbee0e chore: Improve prettier git hook 2023-11-02 10:31:54 -05:00
Aaron Klinker 183bb02e29 chore(deps-dev): Update sass to 1.69.5 2023-11-02 10:26:14 -05:00
Aaron 0bf4ea0897 chore(deps): Upgrade vite to 4.5.0 (#202) 2023-11-02 10:24:50 -05:00
Aaron Klinker cd4d00e23e chore(deps-dev): Update @type/* packages for demo 2023-11-02 10:16:52 -05:00
Aaron Klinker 5de18e5371 chore(deps-dev): Upgrade vitepress to 1.0.0-rc.24 2023-11-02 10:04:33 -05:00
Aaron af823418ee chore(deps): Upgrade giget to ^1.1.3 (#199) 2023-11-02 09:11:17 -05:00
Aaron Klinker 0b8d101c33 chore(deps-dev): Upgrade vue to 3.3.7 2023-11-02 08:58:25 -05:00
Aaron b587849126 chore(deps-dev): Upgrade typedoc to ^0.25.3 (#201) 2023-11-02 08:57:16 -05:00
Aaron 2a35ce0a1e chore(deps-dev): Upgrade execa to ^8.0.1 (#200) 2023-11-02 08:57:06 -05:00
Aaron Klinker c390b70f76 chore(deps): Upgrade unimport to 3.4.0 2023-11-02 08:54:24 -05:00
Aaron Klinker c9fd739128 chore(deps): Upgrade linkedom to 0.16.1 2023-11-02 08:52:22 -05:00
Aaron Klinker 0806c06042 chore(deps): Upgrade jiti to 1.21.0 2023-11-02 08:51:14 -05:00
Aaron Klinker 5f74a544a4 chore(deps-dev): Upgrade lint-staged to ^15.0.2 2023-11-02 08:47:53 -05:00
Aaron Klinker 121778894c chore(deps): Upgrade immer to ^10.0.3 2023-11-02 08:46:25 -05:00
Aaron Klinker 102c72a03c chore(deps): Upgrade esbuild to ^0.19.5 2023-11-02 08:42:16 -05:00
Aaron Klinker a0507866db chore(deps): Upgrade c12 to ^1.5.1 2023-11-02 08:41:05 -05:00
Aaron Klinker f3874da780 chore: Upgrade types 2023-11-02 08:39:47 -05:00
dependabot[bot] cc5d24ec92 chore(deps): bump @types/webextension-polyfill from 0.10.0 to 0.10.5 (#196)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-02 08:05:50 -05:00
dependabot[bot] 08760015da chore(deps-dev): bump tsx from 3.12.8 to 3.14.0 (#198)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-02 08:02:53 -05:00
dependabot[bot] 5368371020 chore(deps): bump filesize from 10.0.12 to 10.1.0 (#197)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-02 08:01:50 -05:00
dependabot[bot] 08d62a437a chore(deps): bump is-wsl from 3.0.0 to 3.1.0 (#195)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-02 08:00:52 -05:00
dependabot[bot] 37e2348d79 chore(deps-dev): bump happy-dom from 12.4.0 to 12.10.3 (#194)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-02 07:59:55 -05:00
GitHub Actions 6a30dc46fa chore(release): v0.8.6 2023-10-30 15:41:46 +00:00
Aaron Klinker b75c553e51 fix: Inline WXT modules inside WxtVitest plugin 2023-10-30 10:25:22 -05:00
GitHub Actions a56face03d chore(release): v0.8.5 2023-10-30 14:54:59 +00:00
Aaron Klinker 19756c61ce docs: Add test.server.deps.inline to Vitest guide 2023-10-30 09:48:52 -05:00
Aaron 5f54b4de17 chore: Reduce package size by 70%, 1.92 MB to 590 kB (#190) 2023-10-29 23:00:10 -05:00
Aaron Klinker ea8935c47c Hide code coverage badge while it's broken 2023-10-29 21:24:21 -05:00
Aaron e37f73880d feat: Refactor project structure to export initialize, prepare, and zip functions (#182) 2023-10-29 21:19:31 -05:00
Aaron Klinker 2e24b9e18a chore: Update template docs 2023-10-29 20:24:38 -05:00
Aaron Klinker f8a0fb37a2 fix: Enable Vue SFC auto-imports in vue template 2023-10-29 20:24:27 -05:00
Nenad Novaković dd26b99027 docs: Update auto-imports.md (#186) 2023-10-29 08:29:54 -05:00
Aaron Klinker d9e9b43f8d docs: Improve runner.binaries documentation 2023-10-25 03:14:53 -05:00
GitHub Actions d580083727 chore(release): v0.8.4 2023-10-20 15:26:38 +00:00
Aaron 5a70d9e57d fix: Allow actions without a popup (#181) 2023-10-20 10:20:40 -05:00
GitHub Actions 1b1af245bd chore(release): v0.8.3 2023-10-18 21:38:14 +00:00
Aaron 874a531a62 feat: Add testing utils under wxt/testing (#178) 2023-10-18 16:28:26 -05:00
GitHub Actions a3d409f250 chore(release): v0.8.2 2023-10-17 20:39:45 +00:00
Aaron b6758ca9fa fix(firefox): Stop extending AbortController to fix crash in content scripts (#176) 2023-10-17 15:33:55 -05:00
Aaron 2672308946 chore: Improve output consistency (#175) 2023-10-16 11:00:33 -05:00
GitHub Actions 7ac171ed3b chore(release): v0.8.1 2023-10-16 14:33:06 +00:00
Aaron Klinker 6a93f20bb3 fix: Output action.browser_style correctly 2023-10-16 09:20:40 -05:00
Aaron Klinker 921af6a5a1 Rename jobs 2023-10-15 15:08:34 -05:00
Aaron Klinker 21ebeacd20 chore(deps): Revert node 20 upgrade due to OOM errors in CI 2023-10-15 14:51:36 -05:00
Aaron 527600031f docs: Generate full API docs with typedoc (#174) 2023-10-14 22:03:23 -05:00
Aaron Klinker 91a804c492 Update changelog 2023-10-14 10:40:36 -05:00
Aaron Klinker 54f3785063 Upgrade templates to use v0.8 2023-10-14 10:40:10 -05:00
GitHub Actions 44e4bc5295 chore(release): v0.8.0 2023-10-14 15:38:11 +00:00
Aaron f464d7d33f chore(deps): Use NodeJS v20 for development (#170) 2023-10-14 10:28:34 -05:00
Aaron d0672739f0 chore(deps): Upgrade vite to 4.4.11 (#169) 2023-10-14 10:19:00 -05:00
Aaron 44464f914f feat!: Use defineUnlistedScript to define unlisted scripts (#167)
BREAKING CHANGE: Unlisted scripts must now `export default defineUnlistedScript(...)`
2023-10-14 10:06:52 -05:00
Aaron 8940c41bdb chore(deps): Upgrade vitest to 0.34.6 (#168) 2023-10-14 10:06:20 -05:00
Aaron Klinker 446f265b6c types!: Rename BackgroundScriptDefintition to BackgroundDefinition 2023-10-14 09:41:07 -05:00
渣渣120 7a465684c0 docs: Fix wrong links (#166) 2023-10-14 08:09:46 -05:00
GitHub Actions 0369316463 chore(release): v0.7.5 2023-10-13 23:13:01 +00:00
Aaron 8b74291d18 fix: Add browser_style to popup options (#165) 2023-10-13 18:06:40 -05:00
Aaron 739b738100 fix: Ignore non-manifest fields when merging content script entries (#164) 2023-10-13 18:01:13 -05:00
Aaron 95442dd39b fix: More consistent version_name generation between browsers (#163) 2023-10-13 17:37:08 -05:00
GitHub Actions 4f82645c08 chore(release): v0.7.4 2023-10-11 15:59:17 +00:00
Aaron d200c376f8 fix: Support react-refresh when pre-rendering HTML pages in dev mode (#158) 2023-10-11 10:52:48 -05:00
Aaron Klinker b58fb02016 docs: Add migration guides 2023-10-07 10:49:31 -05:00
Aaron e1bab6c746 chore: Upgrade templates to v0.7 (#156) 2023-10-07 10:00:36 -05:00
GitHub Actions d10c22fbd9 chore(release): v0.7.3 2023-10-07 14:59:25 +00:00
Aaron da1f7f3ea5 feat: Support JS entrypoints (#155) 2023-10-07 09:53:47 -05:00
GitHub Actions 2659272f8a chore(release): v0.7.2 2023-10-05 22:17:59 +00:00
Aaron 868fd27804 feat: Allow customizing entrypoint options per browser (#154) 2023-10-05 17:12:20 -05:00
Aaron Klinker d9fdcb5b33 fix: Add missing persistent type to defineBackgroundScript 2023-10-05 16:08:03 -05:00
Aaron Klinker 580793158f fix: Default safari to MV2 2023-10-05 16:07:20 -05:00
Aaron Klinker f58d69dc5f docs: Add docs for development and testing 2023-10-02 15:05:47 -05:00
Aaron c9028dd335 docs: Restructure website to improve UX (#149) 2023-10-02 09:42:46 -05:00
dependabot[bot] 6342f59c5e chore(deps-dev): bump typescript from 5.1 to 5.2 (#148)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2023-10-01 17:58:31 -05:00
dependabot[bot] 2d91898452 chore(deps-dev): bump vitest from 0.34.3 to 0.34.6 (#145)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-01 17:36:48 -05:00
dependabot[bot] 4acefd601c chore(deps-dev): bump vitest-mock-extended from 1.2.1 to 1.3.0 (#147)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-01 17:27:00 -05:00
dependabot[bot] 9a2e71b481 chore(deps-dev): bump @faker-js/faker from 8.0.2 to 8.1.0 (#146)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-01 17:26:20 -05:00
dependabot[bot] 6e578f3156 chore(deps-dev): bump @types/fs-extra from 11.0.1 to 11.0.2 (#144)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-01 17:25:42 -05:00
GitHub Actions 474de83e28 chore(release): v0.7.1 2023-10-01 04:18:14 +00:00
Aaron Klinker 65fcfc0064 docs: Add docs for createContentScriptUi 2023-09-30 23:05:07 -05:00
Aaron Klinker 2d4983e88b chore(release): v0.7.1-alpha1 2023-09-30 21:59:20 -05:00
Aaron 4150e42c05 feat: createContentScriptUi helper (#143) 2023-09-30 21:57:57 -05:00
Aaron 8d7150653a Tweak badge colors for readability 2023-09-30 21:57:16 -05:00
Aaron Klinker 61e57b7b7c Remove all from sync-releases script 2023-09-30 12:49:04 -05:00
Aaron Klinker 83add72312 Update breaking change docs 2023-09-30 12:48:22 -05:00
GitHub Actions 3c723d2c92 chore(release): v0.7.0 2023-09-30 17:45:03 +00:00
Aaron Klinker 1eb35c7207 Reduce codecov requirement to 80% 2023-09-30 12:38:14 -05:00
Aaron 725ecf7c64 fix: Reorder typescript paths to give priority to @ and ~ over @@ and ~~ (#142) 2023-09-30 12:33:33 -05:00
Aaron 3847092df4 feat: Content script cssInjectionMode (#141) 2023-09-30 12:32:00 -05:00
Aaron 19b11c236f fix!: Output content script CSS to content-scripts/<name>.css (#140)
BREAKING CHANGE: Content script CSS used to be output to `assets/<name>.css`, but is now `content-scripts/<name>.css` to match the docs.
2023-09-30 12:20:41 -05:00
Aaron Klinker 4b2012c489 fix: Validate transformed manifest correctly 2023-09-30 10:32:57 -05:00
Aaron Klinker 0591050f31 chore: Store user config metadata in memory
This will be used in #16
2023-09-30 10:30:25 -05:00
GitHub Actions b15dc7fc11 chore(release): v0.6.6 2023-09-30 15:05:16 +00:00
Aaron 89d15babc2 feat: Disable opening browser automatically during dev mode (#136) 2023-09-30 08:45:24 -05:00
GitHub Actions c616125689 chore(release): v0.6.5 2023-09-30 03:15:10 +00:00
Aaron e97071b7d7 fix: Support loading tsx entrypoints (#134) 2023-09-29 22:08:20 -05:00
Aaron 1fa049c5a7 Update badge colors 2023-09-29 12:43:28 -05:00
Aaron Klinker b48cee9715 fix: Don't crash when <all_urls> matches is used in dev mode 2023-09-29 08:18:56 -05:00
Aaron Klinker 24e69fe1bf docs: Add link to update extensions using WXT 2023-09-28 12:26:29 -05:00
Aaron Klinker 41e154992a docs: Fix DX section sizing 2023-09-28 12:22:56 -05:00
Aaron Klinker 55707932a9 docs: Add more content to the homepage 2023-09-28 12:08:21 -05:00
Aaron Klinker 08115a40ae Add explicit title to homepage 2023-09-28 10:22:20 -05:00
Aaron Klinker 96be879918 docs: Add tags for SEO and socials 2023-09-28 10:13:18 -05:00
Aaron 1fc4ada66d Add badges to README 2023-09-27 12:41:37 -05:00
Aaron Klinker d27f299641 Remove files from coverage 2023-09-27 12:27:58 -05:00
Aaron 7183114370 chore: Code coverage improvements (#131) 2023-09-27 12:21:50 -05:00
GitHub Actions 7bd940450f chore(release): v0.6.4 2023-09-27 17:12:03 +00:00
Aaron cf5a7d1411 fix: Use execaCommand instead of node:child_process (#130) 2023-09-27 12:06:44 -05:00
Aaron Klinker 5482b2f934 chore: Increase E2E test timeout
GitHub actions windows fails every once in a while due to a timeout, this should reduce those errors
2023-09-27 11:36:37 -05:00
Aaron Klinker c4a6ff928d Remove Aaron from release contributors 2023-09-27 11:34:18 -05:00
Aaron Klinker 455e7f3765 fix(content-scripts): Don't throw an error when including include or exclude options on a content script 2023-09-27 11:29:50 -05:00
Aaron 25b6ab92f5 chore(templates): Add .wxt directory to gitignore (#129) 2023-09-27 11:24:04 -05:00
GitHub Actions 50f6289ac5 chore(release): v0.6.3 2023-09-26 22:28:00 +00:00
Aaron a0e1b4741e feat(client): Add block and addEventListener utils to ContentScriptContext (#128) 2023-09-26 17:19:56 -05:00
GitHub Actions ab672e9dbd chore(release): v0.6.2 2023-09-25 19:31:40 +00:00
Aaron 7b3ea52e02 feat: Show spinner when building entrypoints (#126) 2023-09-25 14:23:19 -05:00
Aaron e0929a68ba docs: Update vite docs to use function 2023-09-25 00:14:38 -05:00
Aaron 4c430725a5 docs: Fix import typo 2023-09-25 00:10:35 -05:00
Aaron 7d745f6ec7 Remove vercel config
Using netlify
2023-09-23 16:17:10 -05:00
Aaron Klinker 10091d7769 Update feature list 2023-09-23 16:05:43 -05:00
Aaron 2e142b3038 feat: --analyze build flag (#125) 2023-09-23 16:00:35 -05:00
GitHub Actions 361bb2dcc8 chore(release): v0.6.1 2023-09-23 02:13:38 +00:00
Aaron 26fca5c0a2 feat: Add transformManifest option (#124) 2023-09-22 21:08:03 -05:00
Aaron 30a61f4384 fix: Don't open browser during development when using WSL (#123) 2023-09-22 20:32:31 -05:00
Aaron Klinker 8e0a189d77 docs: Load extension details from CWS 2023-09-22 14:37:20 -05:00
Aaron Klinker cae44c9732 Update changelog 2023-09-22 12:47:34 -05:00
GitHub Actions fba8f0d017 chore(release): v0.6.0 2023-09-22 17:45:55 +00:00
Aaron Klinker 3f260ee777 fix: Disable dev logs in production
This closes #119
2023-09-22 12:05:05 -05:00
Aaron Klinker 1f6a931b02 fix: Use the same mode for each build step 2023-09-22 11:57:36 -05:00
Aaron 07891d028b feat!: Require a function for vite configuration (#121)
BREAKING CHANGE: The `vite` config option must now be a function. If you were using an object before, change it from `vite: { ... }` to `vite: () => ({ ... })`.
2023-09-22 11:51:55 -05:00
Aaron Klinker 1f448d1bf0 feat: Export ContentScriptContext from wxt/client 2023-09-22 11:00:28 -05:00
Aaron Klinker 7722986537 Update changelog authors 2023-09-22 10:56:22 -05:00
GitHub Actions 4b73168618 chore(release): v0.5.6 2023-09-22 15:48:35 +00:00
Aaron 16cebc538f feat: Add ContentScriptContext util for stopping invalidated content scripts (#120) 2023-09-21 18:48:07 -05:00
Aaron e4aaba98ab Remove defer from umami script 2023-09-20 21:09:30 -05:00
Aaron c190d8c44c Add umami to docs website 2023-09-20 21:08:51 -05:00
GitHub Actions 5801f96f79 chore(release): v0.5.5 2023-09-19 23:00:53 +00:00
Aaron Klinker 92039b855e fix: Automatically replace vite's process.env.NODE_ENV output in lib mode with the mode 2023-09-19 17:56:10 -05:00
GitHub Actions f145e00cc9 chore(release): v0.5.4 2023-09-19 22:39:57 +00:00
Aaron Klinker 87e8df90f5 fix: Don't warn about deep entrypoint subdirectories not being recognized 2023-09-19 17:32:25 -05:00
Aaron Klinker 419fab8193 fix: Recognize background/index.ts as an entrypoint 2023-09-19 17:32:25 -05:00
GitHub Actions 71743b3bf3 chore(release): v0.5.3 2023-09-19 21:40:41 +00:00
Aaron 8e3169eb1e chore: Refactor how config is resolved (#118) 2023-09-19 16:36:00 -05:00
Aaron Klinker 4ec904ea3c fix: Allow function for vite config 2023-09-19 12:53:35 -05:00
GitHub Actions b284305605 chore(release): v0.5.2 2023-09-19 15:55:16 +00:00
Aaron 234bd39a11 fix: Import client utils when getting entrypoint config (#117) 2023-09-19 10:50:41 -05:00
Aaron b5acea106d Bump templates to ^0.5.0 (#116) 2023-09-15 13:57:10 -05:00
GitHub Actions 33ed04ff6b chore(release): v0.5.1 2023-09-15 18:56:09 +00:00
Aaron f51bbc0a68 feat: Include/exclude entrypoints based on target browser (#115) 2023-09-15 13:51:53 -05:00
Aaron 6ee5b22e6c feat: Allow disabling auto-imports (#114) 2023-09-15 12:25:22 -05:00
Aaron Klinker b4de93d2e6 fix: Allow any string for target browser 2023-09-15 12:24:52 -05:00
Aaron Klinker 2570debc5c Update changelog 2023-09-14 15:19:32 -05:00
GitHub Actions e6a2c15d3c chore(release): v0.5.0 2023-09-14 20:14:05 +00:00
Aaron Klinker dbd84c8815 chore: Add entrypoints debug log 2023-09-14 15:03:50 -05:00
Aaron Klinker fe966b6ca8 docs: Add vite customization docs 2023-09-07 19:17:31 -05:00
Aaron Klinker e2350fecc6 docs: Add migration docs 2023-09-07 18:35:37 -05:00
Aaron b33b6631a5 docs: Make README pretty 2023-09-07 18:01:20 -05:00
Aaron Klinker 5f15f9ccec fix!: Change default publicDir to <srcDir>/public
This reverts 19c0948
2023-09-07 17:32:30 -05:00
Aaron Klinker beafa6afc4 docs: Fix typos 2023-09-07 16:14:36 -05:00
Aaron Klinker 46a5036482 docs: Add link to examples repo 2023-09-05 18:59:21 -05:00
dependabot[bot] eaa15e0d57 chore(deps-dev): bump @types/node from 20.5.0 to 20.5.9 (#110)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-05 18:25:22 -05:00
dependabot[bot] 2c22948d2e chore(deps): bump unimport from 3.1.3 to 3.3.0 (#108)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-05 18:25:04 -05:00
dependabot[bot] 3e701e22c9 chore(deps-dev): bump tsx from 3.12.7 to 3.12.8 (#109)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-05 18:23:33 -05:00
dependabot[bot] 6ee1fa17a1 chore(deps-dev): bump prettier from 3.0.1 to 3.0.3 (#111)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-05 18:23:06 -05:00
dependabot[bot] b76bf2831b chore(deps): bump linkedom from 0.15.2 to 0.15.3 (#112)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-05 18:21:04 -05:00
Aaron Klinker ac7cbfce1f chore: Move repo to wxt-dev org 2023-09-05 18:01:59 -05:00
Aaron Klinker 06f027b889 Update cli screenshot 2023-09-05 17:47:37 -05:00
Aaron Klinker e996686082 Update contributors in changelog 2023-09-05 17:36:48 -05:00
Aaron 1bb3474a91 fix(types): Don't write to files if nothing changes (#107) 2023-09-05 17:24:38 -05:00
GitHub Actions 79426671cf chore(release): v0.4.1 2023-09-05 22:15:02 +00:00
Aaron 89b34403ee feat(cli): Add wxt clean command to delete generated files (#106) 2023-09-05 16:21:57 -05:00
Aaron Klinker 749bc38234 Add sync-releases helper script 2023-09-05 10:21:14 -05:00
Aaron Klinker e086374828 fix(init): Don't show cd . when initializing the current directory 2023-09-05 10:21:14 -05:00
Aaron 2c3721e5f4 Upgrade templates to 0.4 (#105) 2023-09-05 10:16:31 -05:00
Aaron Klinker c2946aa1eb Fix changelog contributors 2023-09-05 10:14:22 -05:00
GitHub Actions 4dd6320eae chore(release): v0.4.0 2023-09-05 15:07:59 +00:00
Aaron a8285fff78 feat: Generate types for browser.i18n.getMessage (#103) 2023-09-05 09:55:55 -05:00
Aaron d89be2544d chore: Use import aliases in Vue template (#104) 2023-09-05 09:31:47 -05:00
Aaron f234c85357 fix!: Use relative path aliases inside .wxt/tsconfig.json (#102)
BREAKING CHANGE: Moved .wxt directory from inside srcDir to root to match Nuxt.
2023-09-04 21:48:07 -05:00
Aaron Klinker 93bfee0578 chore: Remove explict icon config from templates
Icons are now automatically discovered thanks to aefc8d3
2023-09-04 15:55:29 -05:00
Aaron Klinker 2c7922ca4c chore: Fix test watcher restarting indefinetly 2023-09-04 15:41:06 -05:00
dependabot[bot] 72ae812c42 chore(deps-dev): bump vitepress from 1.0.0-rc.4 to 1.0.0-rc.10 (#96)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2023-09-03 16:59:04 -05:00
Aaron 2a0842bb62 chore: Increase E2E test timeout because GitHub Actions Window runner is slow 2023-09-02 11:22:34 -05:00
Aaron b301ee324e feat: Replace web-ext with web-ext-run (#101) 2023-09-02 09:47:05 -05:00
dependabot[bot] 4ef3eeaca1 chore(deps-dev): bump vitest from 0.34.1 to 0.34.3 (#99)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-01 17:29:21 -05:00
dependabot[bot] e803bfecb5 chore(deps-dev): bump lint-staged from 14.0.0 to 14.0.1 (#100)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-01 17:06:35 -05:00
dependabot[bot] 0dcf540393 chore(deps): bump linkedom from 0.15.1 to 0.15.2 (#98)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-01 17:05:51 -05:00
dependabot[bot] 062e25d834 chore(deps-dev): bump vitest-mock-extended from 1.2.0 to 1.2.1 (#97)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-01 17:03:19 -05:00
Aaron Klinker b58a15e783 chore: Fix failing demo build 2023-08-29 16:06:43 -05:00
Aaron Klinker 5f5f1d90f8 fix: Don't overwrite wxt.config.ts content scripts, append entrypoints to it 2023-08-29 16:02:47 -05:00
Aaron Klinker 83e62a1d63 chore: Fix remote code E2E test 2023-08-29 16:02:47 -05:00
Aaron Klinker b428a62a90 fix: Allow adding custom content scripts 2023-08-29 15:48:25 -05:00
dependabot[bot] 1fe4eedc9a chore(deps): bump filesize from 10.0.8 to 10.0.12 (#90)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 21:07:26 -05:00
dependabot[bot] 39d3192904 chore(deps-dev): bump lint-staged from 13.3.0 to 14.0.0 (#89)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 21:07:18 -05:00
dependabot[bot] de30509d94 chore(deps-dev): bump vitest-mock-extended from 1.1.4 to 1.2.0 (#87)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 21:07:11 -05:00
dependabot[bot] d5ae2332ca chore(deps): bump linkedom from 0.14.26 to 0.15.1 (#86)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 20:59:18 -05:00
dependabot[bot] f8b367dd7b chore(deps): bump unimport from 3.1.0 to 3.1.3 (#88)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 20:58:07 -05:00
dependabot[bot] 6bcb71baa0 chore(deps-dev): bump vitepress from 1.0.0-beta.5 to 1.0.0-rc.4 (#85)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2023-08-14 20:56:33 -05:00
dependabot[bot] 54bdf54839 chore(deps-dev): bump @vitest/coverage-v8 from 0.32.4 to 0.34.1 (#84)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 20:47:43 -05:00
dependabot[bot] 83f457f40f chore(deps): bump vite from 4.4.7 to 4.4.9 (#82)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2023-08-13 19:30:02 -05:00
dependabot[bot] f9df2d0809 chore(deps-dev): bump tsup from 7.1.0 to 7.2.0 (#80)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-13 15:07:49 -05:00
dependabot[bot] 2b079bb7f6 chore(deps-dev): bump @types/node from 20.4.5 to 20.5.0 (#78)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-13 15:06:03 -05:00
Aaron 0194448af4 Remove generated docs/config.md file (#83) 2023-08-13 14:59:34 -05:00
dependabot[bot] b409def211 chore(deps-dev): bump ora from 6.3.1 to 7.0.1 (#79) 2023-08-13 14:58:02 -05:00
dependabot[bot] 62bbef3487 chore(deps-dev): bump vitest from 0.32.4 to 0.34.1 (#81) 2023-08-13 14:56:47 -05:00
Aaron 87013bc616 Check for updates weekly 2023-08-13 14:52:45 -05:00
Aaron Klinker 4599bf2aa0 Fix dependabot config 2023-08-13 14:41:40 -05:00
Aaron d629acf518 chore: Upgrade to prettier 3 (#77) 2023-08-13 14:39:53 -05:00
Aaron 2bde9175b7 chore: Setup bug and feature issue templates 2023-08-13 14:39:33 -05:00
Aaron 8d5f4f5201 docs: Add contribution guide (#76) 2023-08-13 14:22:17 -05:00
Aaron d05f126eb3 feat: Add --debug flag for printing debug logs for all CLI commands (#75) 2023-08-13 14:04:43 -05:00
Aaron Klinker e164bd51fe chore: Update social preview 2023-08-13 13:18:01 -05:00
Aaron d66293c56e chore: Setup dependabot for upgrading dependencies 2023-08-13 13:15:46 -05:00
GitHub Actions 6aa827438c chore(release): v0.3.2 2023-08-13 17:58:07 +00:00
Aaron 6ee8a43677 docs: Generate markdown for config reference (#74) 2023-08-13 12:51:19 -05:00
Aaron Klinker d54d6111e6 feat: Don't allow auto-importing from subdirectories
This reverts commit 547fee0e0e.

BREAKING CHANGE: 547fee previously added auto imports from subdirectories, but Nuxt does not do this, so to be consistent with Nuxt's DX, I'm also removing these auto-imports.
2023-08-13 10:13:42 -05:00
Aaron aefc8d3167 feat: Discover icons from the public directory (#72) 2023-08-13 10:05:27 -05:00
Aaron 7ccff533ff chore: Improve file list output in CI (#73) 2023-08-13 09:51:22 -05:00
Aaron Klinker edfa075030 ci: Validate templates using tarball to avoid version conflicts within the wxt/node_modules directory 2023-08-13 08:33:26 -05:00
Aaron Klinker ef140dc7f8 ci: List vite version when validating project templates 2023-08-13 08:33:26 -05:00
Aaron Klinker 39467d10f3 docs: Fix capitalization 2023-08-13 08:33:26 -05:00
Aaron Klinker 97f0938c99 docs: Fix typos 2023-08-12 09:21:40 -05:00
Aaron Klinker 18741eae8e Add remote code page to sidebar 2023-07-30 00:06:09 -05:00
Aaron Klinker 3f3ef37c96 Cleanup nuxt similarities 2023-07-30 00:05:14 -05:00
Aaron Klinker 323045a7c3 docs: Document the url: import prefix for remote code 2023-07-29 23:33:28 -05:00
Aaron 9b34180467 ci: Validate templates against main (#66) 2023-07-29 23:21:13 -05:00
Aaron Klinker 7f15305037 chore: Update templates to work with CSS entrypoints 2023-07-29 23:08:42 -05:00
Aaron Klinker 35cc1c94bf Update contributor links in changelog 2023-07-29 22:57:45 -05:00
Aaron Klinker 547c1850ac chore: Upgrade vite (v4.3 &rarr; v4.4) 2023-07-29 22:50:08 -05:00
Aaron Klinker 798f02f626 chore: Upgrade dependencies 2023-07-29 22:49:00 -05:00
Aaron Klinker d5948abfe5 Update changelog 2023-07-29 22:39:42 -05:00
GitHub Actions ec01f048ed chore(release): v0.3.1 2023-07-30 03:35:56 +00:00
Aaron Klinker 8751c55063 Switch back to default reporter for CI 2023-07-29 22:27:17 -05:00
Aaron Klinker dfe424f35d chore: Increate E2E test timeout to fix flakey test 2023-07-29 22:26:05 -05:00
Aaron Klinker 25677ba445 ci: Fix flakey failure when validating templates 2023-07-29 22:24:38 -05:00
Aaron Klinker 390f65cf39 Add bootstrap command to docs 2023-07-29 22:22:35 -05:00
Aaron 310f994ccb feat: init command for bootstrapping new projects (#65) 2023-07-29 22:20:31 -05:00
Aaron Klinker 23e4295e08 Fix typo 2023-07-29 15:59:03 -05:00
Aaron Klinker abdef08aeb Fix typos in publishing docs 2023-07-29 15:21:07 -05:00
Aaron Klinker 38d4f9c879 docs: Add a comparison page to compare and contrast against Plasmo 2023-07-29 15:20:55 -05:00
Aaron Klinker 709b61a174 docs: Add a section for extensions using WXT 2023-07-29 15:00:25 -05:00
Aaron Klinker 4184b0529d docs: Add publishing docs 2023-07-22 10:46:45 -05:00
Aaron d3ff4c6afe Cleanup templates (#64) 2023-07-22 09:10:59 -05:00
BeanWei 16de4da27f chore: Add Solid template (#63)
Co-authored-by: Aaron Klinker <aklinker1@users.noreply.github.com>
2023-07-22 08:43:10 -05:00
Aaron 936d83bc08 chore: Simplify binary setup (#62) 2023-07-21 19:58:57 -05:00
Aaron Klinker aea866c9cd docs: Update installation docs 2023-07-21 14:10:34 -05:00
Aaron Klinker 3107d27184 Fix copy-paste error for sidepanel docs 2023-07-21 13:50:23 -05:00
Aaron Klinker 3a336eba89 docs: Add output paths to entrypoint docs 2023-07-21 13:47:29 -05:00
Aaron 044a24fd6a feat: CSS entrypoints (#61) 2023-07-21 12:57:09 -05:00
Aaron Klinker 5b269f4369 Remove gradient from hero logo 2023-07-21 09:19:41 -05:00
Aaron 7d55faff20 chore: Branding and logo (#60) 2023-07-21 01:51:04 -05:00
Aaron Klinker 386f8db5db Update readme features 2023-07-20 23:30:41 -05:00
Aaron Klinker 94a1097df5 docs: Add zip command to installation scripts 2023-07-20 23:26:20 -05:00
Aaron be95a778ab chore: Update template projects to v0.3 (#56) 2023-07-20 23:13:20 -05:00
Aaron Klinker d3b1536f39 Update changelog 2023-07-20 23:01:46 -05:00
Aaron Klinker 9f2b989a2f Merge branch 'main' of github.com:aklinker1/wxt 2023-07-20 23:00:31 -05:00
Aaron Klinker 3a9fd3909f ci: Speed up demo validation 2023-07-20 22:53:51 -05:00
455 changed files with 25382 additions and 8319 deletions
+8
View File
@@ -0,0 +1,8 @@
coverage:
status:
project:
default:
informational: true
patch:
default:
informational: true
+3
View File
@@ -1,2 +1,5 @@
* text=auto eol=lf
pnpm-lock.yaml linguist-generated
package-lock.json linguist-generated
bun.lockb linguist-generated
yarn.lock linguist-generated
+50
View File
@@ -0,0 +1,50 @@
---
name: Bug report
about: Report an issue with WXT
title: ''
labels: triage
assignees: ''
---
### Describe the bug
A clear and concise description of what the bug is.
### To Reproduce
Share minimal reproduction. Examples of a minimal reproduction:
- PR with a failing test case
- ZIP file containing a minimal WXT project (be sure to include your lockfile!!)
> **_⚠️ If you don't upload a minimal reproduction, your issue will be closed until a reproduction is added._**
>
> Why? https://antfu.me/posts/why-reproductions-are-required
Steps to reproduce the bug using the reproduction:
1. Install dependencies: `pnpm i`
2. Start dev mode: `pnpm dev`
3. Click this...
4. Do that...
5. Etc...
### Expected behavior
A clear and concise description of what you expected to happen.
### Screenshots
If applicable, add screenshots to help explain your problem.
### Environment
<!--- Run `npx envinfo --system --browsers --binaries --npmPackages wxt,vite` and paste the output below -->
```
Paste output here
```
### Additional context
Add any other context about the problem here, otherwise you can delete this section.
+23
View File
@@ -0,0 +1,23 @@
---
name: Feature request
about: Suggest an idea for WXT
title: ''
labels: feature
assignees: ''
---
### Feature Request
Please describe your feature, be clear and concise. If you have a proposal for required type or API changes, list them here.
#### Is your feature request related to a bug?
If so, add a link here. If not, write "N/A"
### What are the alternatives?
A clear and concise description of any alternative solutions or features you've considered.
### Additional context
Add any other context or screenshots about the feature request here.
+17
View File
@@ -0,0 +1,17 @@
name: Basic Setup
description: Install PNPM, Node, and dependencies
runs:
using: composite
steps:
- name: Setup PNPM
uses: pnpm/action-setup@v3
with:
version: 8
- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version: 18
cache: pnpm
- name: Install Dependencies
shell: bash
run: pnpm install
+15
View File
@@ -0,0 +1,15 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: npm
directory: '/' # Location of package manifests
schedule:
interval: 'monthly'
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'monthly'
+27
View File
@@ -0,0 +1,27 @@
name: Publish Docs
on:
push:
branches:
- main
workflow_dispatch:
inputs:
tag:
description: Docker Image Tag
required: true
default: latest
jobs:
publish:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- uses: docker/login-action@v3
with:
registry: https://${{ secrets.DOCKER_REGISTRY_HOSTNAME }}
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
- run: pnpm docs:build
- run: docker build docs/.vitepress -t ${{ secrets.DOCKER_REGISTRY_HOSTNAME }}/wxt/docs:${{ github.event.inputs.tag || 'latest' }}
- run: docker push ${{ secrets.DOCKER_REGISTRY_HOSTNAME }}/wxt/docs:${{ github.event.inputs.tag || 'latest' }}
- run: curl -X POST -i ${{ secrets.UPDATE_DOCS_WEBHOOK }}
+6 -18
View File
@@ -5,33 +5,18 @@ on:
jobs:
validate:
uses: './.github/workflows/validate.yml'
secrets: inherit
publish:
runs-on: ubuntu-22.04
needs:
- validate
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup PNPM
uses: pnpm/action-setup@v2
with:
version: 8
- name: Setup NodeJS
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'pnpm'
- name: Install dependencies
run: |
pnpm install --ignore-scripts
pnpm build
pnpm install --ignore-scripts
- uses: ./.github/actions/setup
- name: Bump and Tag
run: |
@@ -40,11 +25,14 @@ jobs:
pnpx changelogen@latest --release
git push
git push --tags
working-directory: packages/wxt
- name: NPM
run: |
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" > ~/.npmrc
pnpm publish
working-directory: packages/wxt
- name: GitHub Release
run: pnpx changelogen@latest gh release --token ${{ secrets.GITHUB_TOKEN }}
working-directory: packages/wxt
+23
View File
@@ -0,0 +1,23 @@
name: Sync Releases
on:
workflow_dispatch:
push:
branches:
- main
paths:
- packages/wxt/CHANGELOG.md
jobs:
sync:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: 18
cache: pnpm
- run: pnpm sync-releases all --token ${{ secrets.GITHUB_TOKEN }}
working-directory: packages/wxt
+57 -91
View File
@@ -7,96 +7,62 @@ on:
- main
jobs:
wxt:
name: WXT
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PNPM
uses: pnpm/action-setup@v2
with:
version: 8
- name: Setup NodeJS
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'pnpm'
- name: Install dependencies
run: |
pnpm install --ignore-scripts
pnpm build
pnpm install --ignore-scripts
cd demo && pnpm wxt prepare
- name: Formatting
run: pnpm format:check
- name: Type Check
run: pnpm compile
- name: Build Demo
run: |
pnpm build:all:chrome-mv2
pnpm build:all:chrome-mv3
pnpm build:all:firefox-mv2
pnpm build:all:firefox-mv3
pnpm compile
pnpm zip
working-directory: demo
- name: Tests
run: pnpm test:coverage --reporter=default --reporter=hanging-process
project-templates:
name: Project Templates
checks:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PNPM
uses: pnpm/action-setup@v2
with:
version: 8
- name: Setup NodeJS
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'pnpm'
- name: Validate Vanilla
working-directory: templates/vanilla
run: |
npm i
npm run build
npm run compile
- name: Validate Vue
working-directory: templates/vue
run: |
npm i
npm run build
npm run compile
- name: Validate React
working-directory: templates/react
run: |
npm i
npm run build
npm run compile
- name: Validate Svelte
working-directory: templates/svelte
run: |
npm i
npm run build
npm run check
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: pnpm check
build-demo:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: pnpm build:all
working-directory: packages/wxt-demo
- run: pnpm wxt zip
working-directory: packages/wxt-demo
tests:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- uses: oven-sh/setup-bun@v1
- name: pnpm test:coverage
run: pnpm test:coverage --reporter=default --reporter=hanging-process
- uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
windows-tests:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: pnpm test run
template:
runs-on: ubuntu-22.04
strategy:
matrix:
template:
- react
- solid
- svelte
- vanilla
- vue
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: pnpm pack
working-directory: packages/wxt
- run: npm i
working-directory: templates/${{ matrix.template }}
- run: npm i -D ../../packages/wxt/wxt-*.tgz
working-directory: templates/${{ matrix.template }}
- run: pnpm compile
if: matrix.template != 'svelte'
working-directory: templates/${{ matrix.template }}
- run: pnpm check
if: matrix.template == 'svelte'
working-directory: templates/${{ matrix.template }}
- run: pnpm build
working-directory: templates/${{ matrix.template }}
+3 -1
View File
@@ -10,7 +10,6 @@
/docs/.vitepress/cache
coverage
dist
e2e/project
node_modules
TODOs.md
web-ext.config.js
@@ -18,3 +17,6 @@ web-ext.config.ts
templates/*/pnpm-lock.yaml
templates/*/yarn.lock
templates/*/package-lock.json
docs/api
stats.html
.tool-versions
-1
View File
@@ -1 +0,0 @@
ignore-workspace-root-check=true
+1 -1
View File
@@ -1,7 +1,7 @@
.output
coverage
dist
e2e/project
.wxt
docs/.vitepress/cache
pnpm-lock.yaml
CHANGELOG.md
-1
View File
@@ -1,3 +1,2 @@
singleQuote: true
trailingComma: all
endOfLine: lf
-392
View File
@@ -1,392 +0,0 @@
# Changelog
## v0.3.0
[compare changes](https://github.com/aklinker1/wxt/compare/v0.2.5...v0.3.0)
### 🚀 Enhancements
- ⚠️ Add type safety to `browser.runtime.getURL` ([58a84ec](https://github.com/aklinker1/wxt/commit/58a84ec))
- ⚠️ Change default `publicDir` to `<rootDir>/public` ([19c0948](https://github.com/aklinker1/wxt/commit/19c0948))
- Windows support ([#50](https://github.com/aklinker1/wxt/pull/50))
### 🩹 Fixes
- Add `WebWorker` lib to generated tsconfig ([2c70246](https://github.com/aklinker1/wxt/commit/2c70246))
### 📖 Documentation
- Update entrypoint directory links ([0aebb67](https://github.com/aklinker1/wxt/commit/0aebb67))
### 🌊 Types
- Allow any string for the __BROWSER__ global ([6092235](https://github.com/aklinker1/wxt/commit/6092235))
### 🤖 CI
- Improve checks against `demo/` extension ([9cc464f](https://github.com/aklinker1/wxt/commit/9cc464f))
#### ⚠️ Breaking Changes
- ⚠️ Add type safety to `browser.runtime.getURL` ([58a84ec](https://github.com/aklinker1/wxt/commit/58a84ec))
- ⚠️ Change default `publicDir` to `<rootDir>/public` ([19c0948](https://github.com/aklinker1/wxt/commit/19c0948))
### ❤️ Contributors
- Aaron
- Aaron Klinker
## v0.2.5
[compare changes](https://github.com/aklinker1/wxt/compare/v0.2.4...v0.2.5)
### 🚀 Enhancements
- Auto-import from subdirectories ([547fee0](https://github.com/aklinker1/wxt/commit/547fee0))
- Include background script in dev mode if user doesn't define one ([ca20a21](https://github.com/aklinker1/wxt/commit/ca20a21))
### 🩹 Fixes
- Don't crash when generating types in dev mode ([d8c1903](https://github.com/aklinker1/wxt/commit/d8c1903))
- Properly load entrypoints that reference `import.meta` ([54b18cc](https://github.com/aklinker1/wxt/commit/54b18cc))
### 🏡 Chore
- Update templates to wxt@0.2 ([9d00eb2](https://github.com/aklinker1/wxt/commit/9d00eb2))
### 🤖 CI
- Validate project templates ([9ac756f](https://github.com/aklinker1/wxt/commit/9ac756f))
### ❤️ Contributors
- Aaron Klinker
## v0.2.4
[compare changes](https://github.com/aklinker1/wxt/compare/v0.2.3...v0.2.4)
### 🚀 Enhancements
- Add `wxt zip` command ([#47](https://github.com/aklinker1/wxt/pull/47))
### ❤️ Contributors
- Aaron
## v0.2.3
[compare changes](https://github.com/aklinker1/wxt/compare/v0.2.2...v0.2.3)
### 🩹 Fixes
- Correctly lookup open port ([#45](https://github.com/aklinker1/wxt/pull/45))
- Read boolean maniest options from meta tags correctly ([495c5c8](https://github.com/aklinker1/wxt/commit/495c5c8))
- Some fields cannot be overridden from `config.manifest` ([#46](https://github.com/aklinker1/wxt/pull/46))
### ❤️ Contributors
- Aaron Klinker
## v0.2.2
[compare changes](https://github.com/aklinker1/wxt/compare/v0.2.1...v0.2.2)
### 🩹 Fixes
- Register content scripts correctly in dev mode ([2fb5a54](https://github.com/aklinker1/wxt/commit/2fb5a54))
### ❤️ Contributors
- Aaron Klinker
## v0.2.1
[compare changes](https://github.com/aklinker1/wxt/compare/v0.2.0...v0.2.1)
### 🚀 Enhancements
- Support all content script options ([6f5bf89](https://github.com/aklinker1/wxt/commit/6f5bf89))
### 🩹 Fixes
- Remove HMR log ([90fa6bf](https://github.com/aklinker1/wxt/commit/90fa6bf))
### ❤️ Contributors
- Aaron Klinker
## v0.2.0
[compare changes](https://github.com/aklinker1/wxt/compare/v0.1.6...v0.2.0)
### 🚀 Enhancements
- ⚠️ Rename `defineBackgroundScript` to `defineBackground` ([5b48ae9](https://github.com/aklinker1/wxt/commit/5b48ae9))
- Recongize unnamed content scripts (`content.ts` and `content/index.ts`) ([3db5cec](https://github.com/aklinker1/wxt/commit/3db5cec))
### 📖 Documentation
- Update templates ([f28a29e](https://github.com/aklinker1/wxt/commit/f28a29e))
- Add docs for each type of entrypoint ([77cbfc1](https://github.com/aklinker1/wxt/commit/77cbfc1))
- Add inline JSDoc for public types ([375a2a6](https://github.com/aklinker1/wxt/commit/375a2a6))
### 🏡 Chore
- Run `wxt prepare` on `postinstall` ([c1ea9ba](https://github.com/aklinker1/wxt/commit/c1ea9ba))
- Don't format lockfile ([5c7e041](https://github.com/aklinker1/wxt/commit/5c7e041))
#### ⚠️ Breaking Changes
- ⚠️ Rename `defineBackgroundScript` to `defineBackground` ([5b48ae9](https://github.com/aklinker1/wxt/commit/5b48ae9))
### ❤️ Contributors
- Aaron Klinker
## v0.1.6
[compare changes](https://github.com/aklinker1/wxt/compare/v0.1.5...v0.1.6)
### 🩹 Fixes
- Resolve tsconfig paths in vite ([ea92a27](https://github.com/aklinker1/wxt/commit/ea92a27))
- Add logs when a hot reload happens ([977246f](https://github.com/aklinker1/wxt/commit/977246f))
### 🏡 Chore
- React and Vue starter templates ([#33](https://github.com/aklinker1/wxt/pull/33))
- Svelte template ([#34](https://github.com/aklinker1/wxt/pull/34))
### ❤️ Contributors
- Aaron Klinker
- Aaron
## v0.1.5
[compare changes](https://github.com/aklinker1/wxt/compare/v0.1.4...v0.1.5)
### 🩹 Fixes
- Include `vite/client` types ([371be99](https://github.com/aklinker1/wxt/commit/371be99))
### ❤️ Contributors
- Aaron Klinker
## v0.1.4
[compare changes](https://github.com/aklinker1/wxt/compare/v0.1.3...v0.1.4)
### 🩹 Fixes
- Fix regression where manifest was not listed first in build summary ([fa2b656](https://github.com/aklinker1/wxt/commit/fa2b656))
- Fix config hook implementations for vite plugins ([49965e7](https://github.com/aklinker1/wxt/commit/49965e7))
### 📖 Documentation
- Update CLI screenshot ([0a26673](https://github.com/aklinker1/wxt/commit/0a26673))
### 🏡 Chore
- Update prettier ignore ([68611ae](https://github.com/aklinker1/wxt/commit/68611ae))
### ❤️ Contributors
- Aaron Klinker
## v0.1.3
[compare changes](https://github.com/aklinker1/wxt/compare/v0.1.2...v0.1.3)
### 🚀 Enhancements
- Add tsconfig path aliases ([#32](https://github.com/aklinker1/wxt/pull/32))
### 🩹 Fixes
- Merge `manifest` option from both inline and user config ([05ca998](https://github.com/aklinker1/wxt/commit/05ca998))
- Cleanup build summary with sourcemaps ([ac0b28e](https://github.com/aklinker1/wxt/commit/ac0b28e))
### 📖 Documentation
- Create documentation site ([#31](https://github.com/aklinker1/wxt/pull/31))
### 🏡 Chore
- Upgrade to pnpm 8 ([0ce7c9d](https://github.com/aklinker1/wxt/commit/0ce7c9d))
### ❤️ Contributors
- Aaron Klinker
## v0.1.2
[compare changes](https://github.com/aklinker1/wxt/compare/v0.1.1...v0.1.2)
### 🚀 Enhancements
- Accept a function for `config.manifest` ([ee49837](https://github.com/aklinker1/wxt/commit/ee49837))
### 🩹 Fixes
- Add missing types for `webextension-polyfill` and the `manifest` option ([636aa48](https://github.com/aklinker1/wxt/commit/636aa48))
- Only add imports to JS files ([b29c3c6](https://github.com/aklinker1/wxt/commit/b29c3c6))
- Generate valid type for `EntrypointPath` when there are no entrypoints ([6e7184d](https://github.com/aklinker1/wxt/commit/6e7184d))
### 🌊 Types
- Change `config.vite` to `UserConfig` ([ef6001e](https://github.com/aklinker1/wxt/commit/ef6001e))
### ❤️ Contributors
- Aaron Klinker
## v0.1.1
[compare changes](https://github.com/aklinker1/wxt/compare/v0.1.0...v0.1.1)
### 🩹 Fixes
- Allow dashes in entrypoint names ([2e51e73](https://github.com/aklinker1/wxt/commit/2e51e73))
- Unable to read entrypoint options ([#28](https://github.com/aklinker1/wxt/pull/28))
### ❤️ Contributors
- Aaron Klinker
## v0.1.0
Initial release of WXT. Full support for production builds and initial toolkit for development:
- HMR support when HTML page dependencies change
- Reload extension when background changes
- Reload HTML pages when saving them directly
- Re-register and reload tabs when content scripts change
[compare changes](https://github.com/aklinker1/wxt/compare/v0.0.2...v0.1.0)
### 🚀 Enhancements
- Content scripts reloading ([#25](https://github.com/aklinker1/wxt/pull/25))
### 📖 Documentation
- Update feature list ([0255028](https://github.com/aklinker1/wxt/commit/0255028))
### 🤖 CI
- Create github release ([b7c078f](https://github.com/aklinker1/wxt/commit/b7c078f))
### ❤️ Contributors
- Aaron Klinker
## v0.0.2
[compare changes](https://github.com/aklinker1/wxt/compare/v0.0.1...v0.0.2)
### 🚀 Enhancements
- Reload extension when source code is changed ([#17](https://github.com/aklinker1/wxt/pull/17))
- Setup background script web socket/reload ([#22](https://github.com/aklinker1/wxt/pull/22))
- Reload HTML files individually ([#23](https://github.com/aklinker1/wxt/pull/23))
### 🩹 Fixes
- Output chunks to a chunks directory ([2dd7a99](https://github.com/aklinker1/wxt/commit/2dd7a99))
- Remove hash from content script css outputs ([#20](https://github.com/aklinker1/wxt/pull/20))
- Overwrite files with the same name when renaming entrypoints in dev mode ([37986bf](https://github.com/aklinker1/wxt/commit/37986bf))
- Separate template builds to prevent sharing chunks ([7f3a1e8](https://github.com/aklinker1/wxt/commit/7f3a1e8))
- Show Vite warnings and errors ([c51f0e0](https://github.com/aklinker1/wxt/commit/c51f0e0))
### 📖 Documentation
- Add milestone progress badge to README ([684197d](https://github.com/aklinker1/wxt/commit/684197d))
- Fix milestone link in README ([e14f81d](https://github.com/aklinker1/wxt/commit/e14f81d))
### 🏡 Chore
- Refactor build output type ([#19](https://github.com/aklinker1/wxt/pull/19))
- Refactor build outputs to support transpiled templates ([a78aada](https://github.com/aklinker1/wxt/commit/a78aada))
- Rename `templates` to `virtual-modules` ([#24](https://github.com/aklinker1/wxt/pull/24))
- Update cli screenshot ([54eb118](https://github.com/aklinker1/wxt/commit/54eb118))
### ❤️ Contributors
- Aaron Klinker
## v0.0.1
[compare changes](https://github.com/aklinker1/wxt/compare/v0.0.0...v0.0.1)
### 🚀 Enhancements
- Add logger to config ([232ff7a](https://github.com/aklinker1/wxt/commit/232ff7a))
- Export and bootstrap the `/client` package ([5b07c95](https://github.com/aklinker1/wxt/commit/5b07c95))
- Resolve entrypoints based on filesystem ([a63f061](https://github.com/aklinker1/wxt/commit/a63f061))
- Separate output directories for each browser/manifest version ([f09ffbb](https://github.com/aklinker1/wxt/commit/f09ffbb))
- Build entrypoints and output `manfiest.json` ([1e7c738](https://github.com/aklinker1/wxt/commit/1e7c738))
- Automatically add CSS files to content scripts ([047ce04](https://github.com/aklinker1/wxt/commit/047ce04))
- Download and bundle remote URL imports ([523c7df](https://github.com/aklinker1/wxt/commit/523c7df))
- Generate type declarations and config for project types and auto-imports ([21debad](https://github.com/aklinker1/wxt/commit/21debad))
- Good looking console output ([e2cc995](https://github.com/aklinker1/wxt/commit/e2cc995))
- Dev server working and a valid extension is built ([505e419](https://github.com/aklinker1/wxt/commit/505e419))
- Virtualized content script entrypoint ([ca29537](https://github.com/aklinker1/wxt/commit/ca29537))
- Provide custom, typed globals defined by Vite ([8c59a1c](https://github.com/aklinker1/wxt/commit/8c59a1c))
- Copy public directory to outputs ([1a25f2b](https://github.com/aklinker1/wxt/commit/1a25f2b))
- Support browser and chrome styles for mv2 popups ([7945c94](https://github.com/aklinker1/wxt/commit/7945c94))
- Support browser and chrome styles for mv2 popups ([7abb577](https://github.com/aklinker1/wxt/commit/7abb577))
- Support more CLI flags for `build` and `dev` ([#9](https://github.com/aklinker1/wxt/pull/9))
- Add more supported browser types ([f114c5b](https://github.com/aklinker1/wxt/commit/f114c5b))
- Open browser when starting dev server ([#11](https://github.com/aklinker1/wxt/pull/11))
### 🩹 Fixes
- Support `srcDir` config ([739d19f](https://github.com/aklinker1/wxt/commit/739d19f))
- Root path customization now works ([4faa3b3](https://github.com/aklinker1/wxt/commit/4faa3b3))
- Print durations as ms/s based on total time ([3e37de9](https://github.com/aklinker1/wxt/commit/3e37de9))
- Don't print error twice when background crashes ([407627c](https://github.com/aklinker1/wxt/commit/407627c))
- Load package.json from root not cwd ([3ca16ee](https://github.com/aklinker1/wxt/commit/3ca16ee))
- Only allow a single entrypoint with a given name ([8eb4e86](https://github.com/aklinker1/wxt/commit/8eb4e86))
- Respect the mv2 popup type ([0f37ceb](https://github.com/aklinker1/wxt/commit/0f37ceb))
- Respect background type and persistent manifest options ([573ef80](https://github.com/aklinker1/wxt/commit/573ef80))
- Make content script array orders consistent ([f380378](https://github.com/aklinker1/wxt/commit/f380378))
- Firefox manifest warnings in dev mode ([50bb845](https://github.com/aklinker1/wxt/commit/50bb845))
### 📖 Documentation
- Update README ([785ea54](https://github.com/aklinker1/wxt/commit/785ea54))
- Update README ([99ccadb](https://github.com/aklinker1/wxt/commit/99ccadb))
- Update description ([07a262e](https://github.com/aklinker1/wxt/commit/07a262e))
- Update README ([58a0ef4](https://github.com/aklinker1/wxt/commit/58a0ef4))
- Update README ([23ed6f7](https://github.com/aklinker1/wxt/commit/23ed6f7))
- Add initial release milestone link to README ([b400e54](https://github.com/aklinker1/wxt/commit/b400e54))
- Fix typo in README ([5590c9d](https://github.com/aklinker1/wxt/commit/5590c9d))
### 🏡 Chore
- Refactor cli files into their own directory ([e6c0d84](https://github.com/aklinker1/wxt/commit/e6c0d84))
- Simplify `BuildOutput` type ([1f6c4a0](https://github.com/aklinker1/wxt/commit/1f6c4a0))
- Move `.exvite` directory into `srcDir` instead of `root` ([53fb805](https://github.com/aklinker1/wxt/commit/53fb805))
- Refactor CLI commands ([b8952b6](https://github.com/aklinker1/wxt/commit/b8952b6))
- Improve build summary sorting ([ec57e8c](https://github.com/aklinker1/wxt/commit/ec57e8c))
- Remove comments ([e3e9c0d](https://github.com/aklinker1/wxt/commit/e3e9c0d))
- Refactor internal config creation ([7c634f4](https://github.com/aklinker1/wxt/commit/7c634f4))
- Check virtual entrypoints feature in README ([70208f4](https://github.com/aklinker1/wxt/commit/70208f4))
- Add E2E tests and convert to vitest workspace ([5813302](https://github.com/aklinker1/wxt/commit/5813302))
- Rename package to wxt ([51a1072](https://github.com/aklinker1/wxt/commit/51a1072))
- Fix header log's timestamp ([8ca5657](https://github.com/aklinker1/wxt/commit/8ca5657))
- Fix demo global usage ([1ecfedd](https://github.com/aklinker1/wxt/commit/1ecfedd))
- Refactor folder structure ([9ab3953](https://github.com/aklinker1/wxt/commit/9ab3953))
- Fix release workflow ([2e94f2a](https://github.com/aklinker1/wxt/commit/2e94f2a))
### 🤖 CI
- Create validation workflow ([#12](https://github.com/aklinker1/wxt/pull/12))
- Create release workflow ([#13](https://github.com/aklinker1/wxt/pull/13))
### ❤️ Contributors
- Aaron Klinker
+114
View File
@@ -0,0 +1,114 @@
# Contributing
Everyone is welcome to contribute to WXT!
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.
## Conventional Commits
This project uses [Conventional Commits](https://www.conventionalcommits.org/en) to automate versioning. If you're a new contributor, don't worry about this. When you open a PR, a maintainer will change the PR's title so it's in the style of conventional commits, but that's all.
Maintainers, commits to the `main` branch (either directly or via PRs) must be valid conventional commits.
## Setup
WXT uses `pnpm`, so make sure you have it installed.
```sh
corepack enable
```
Then, simply run the install command:
```sh
pnpm i
```
## Development
Here are some helpful commands:
```sh
# Build WXT package
pnpm build
```
```sh
# Build WXT package, then build demo extension
cd demo
pnpm build
```
```sh
# Build WXT package, then start the demo extension in dev mode
cd demo
pnpm dev
```
```sh
# Run unit and E2E tests
pnpm test
```
```sh
# Start the docs website locally
pnpm docs:dev
```
## Updating Docs
Documentation is written with VitePress, and is located in the `docs/` directory.
The API reference is generated from JSDoc comments in the source code. If there's a typo or change you want to make in there, you'll need to update the source code instead of a file in the `docs/` directory.
## Testing
WXT has unit and E2E tests. When making a change or adding a feature, make sure to update the tests or add new ones, if they exist.
> If they don't exist, feel free to create them, but that's a lot for a one-time contributor. A maintainer might add them to your PR though.
To run tests for a specific file, add the filename at the end of the test command:
```sh
pnpm test manifest-contents
```
Unit and E2E tests are ran together via [Vitest workspaces](https://vitest.dev/guide/#workspaces-support).
If you want to manually test a change, you can modify the demo project for your test, but please don't leave those changes committed once you open a PR.
## Templates
Each directory inside `templates/` is it's own standalone project. Simply `cd` into the directory you're updating, install dependencies with `npm` (NOT `pnpm`), and run the relevant commands
```sh
cd templates/vue
npm i
npm run dev
npm run build
```
Note that templates are hardcoded to a specific version of `wxt` from NPM, they do not use the local version. PR checks will test your changes against the templates, but if you want to manually do it, update the package.json dependency:
```diff
"devDependencies": {
"typescript": "^5.3.2",
"vite-plugin-solid": "^2.7.0",
- "wxt": "^0.8.0"
+ "wxt": "../.."
}
```
Then run `npm i` again.
### Adding Templates
To add a template, copy the vanilla template and give it a new name.
```sh
cp -r templates/vanilla templates/<new-template-name>
```
That's it. Once your template is merged, it will be available inside `wxt init` immediately. You don't need to release a new version of WXT to release a new template.
+52 -14
View File
@@ -1,32 +1,70 @@
<h1 align="center">WXT</h1>
<h1 align="center">
<img style="vertical-align:middle" width="44" src="./docs/public/hero-logo.svg" alt="WXT Logo">
<span>WXT</span>
</h1>
<p align="center"><i>Next gen framework for developing web extensions.<br/>Powered by <a href="https://vitejs.dev/" target="_blank">Vite</a>. Inspired by <a href="https://nuxt.com/" target="_blank">Nuxt</a>.</i></p>
<p align="center">
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="npm" 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="npm" 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="NPM" 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="Codecov" src="https://img.shields.io/codecov/c/github/wxt-dev/wxt?labelColor=black&color=%234fa048"></a>
</p>
<p align="center">
<span>Next-gen framework for developing web extensions.</span>
<br/>
<span>⚡</span>
<br/>
<q><i>It's like Nuxt, but for Chrome Extensions</i></q>
</p>
<p align="center">
<a href="https://wxt.dev" target="_blank">Get Started</a>
&bull;
<a href="https://wxt.dev/guide/installation.html" target="_blank">Installation</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://discord.gg/ZFsZqGery9" target="_blank">Discord</a>
</p>
![Example CLI Output](./docs/assets/cli-output.png)
## Demo
https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
## Quick Start
Bootstrap a new project:
```sh
pnpm dlx wxt@latest init <project-name>
```
Or see the [installation guide](https://wxt.dev/guide/installation.html) to get started with WXT.
## Features
- 🌐 Supports all browsers
- ✅ Supports both MV2 and MV3
- ⚡ Dev mode with HMR & auto-reload
- ⚡ Dev mode with HMR & fast reload
- 📂 File based entrypoints
- 🚔 TypeScript
- 🦾 Auto-imports
- ⬇️ Download and bundle remote URL imports
- 🤖 Automated publishing
- 🎨 Frontend framework agnostic: works with Vue, React, Svelte, etc
### Todo
- 🖍️ Quickly bootstrap a new project
- 📏 Bundle analysis
- 🤖 Automated publishing
## Get Started
Checkout the [installation guide](https://wxt.dev/get-started/installation.html) to get started with WXT.
- ⬇️ Download and bundle remote URL imports
## Contributors
<a href="https://github.com/aklinker1/wxt/graphs/contributors">
<img src="https://contrib.rocks/image?repo=aklinker1/wxt" />
<a href="https://github.com/wxt-dev/wxt/graphs/contributors">
<img src="https://contrib.rocks/image?repo=wxt-dev/wxt" />
</a>
-25
View File
@@ -1,25 +0,0 @@
{
"name": "WXT Demo",
"version": "1.0.0",
"description": "Demo extension for WXT",
"type": "module",
"scripts": {
"dev": "pnpm -w build && wxt",
"build": "pnpm -w build && wxt build",
"build:all": "pnpm -w build && run-s -s build:all:*",
"build:all:chrome-mv3": "wxt build",
"build:all:chrome-mv2": "wxt build --mv2",
"build:all:firefox-mv3": "wxt build -b firefox --mv3",
"build:all:firefox-mv2": "wxt build -b firefox",
"zip": "pnpm -w build && wxt zip",
"compile": "pnpm -w build && tsc --noEmit",
"postinstall": "pnpm -w build && wxt prepare"
},
"dependencies": {
"webextension-polyfill": "^0.10.0"
},
"devDependencies": {
"@types/webextension-polyfill": "^0.10.0",
"wxt": "workspace:*"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

-15
View File
@@ -1,15 +0,0 @@
export default defineBackground(() => {
console.log(browser.runtime.id);
logId();
console.log({
browser: __BROWSER__,
chrome: __IS_CHROME__,
firefox: __IS_FIREFOX__,
manifestVersion: __MANIFEST_VERSION__,
});
// @ts-expect-error: should only accept entrypoints or public assets
browser.runtime.getURL('/');
browser.runtime.getURL('/background.js');
browser.runtime.getURL('/icon/128.png');
});
-5
View File
@@ -1,5 +0,0 @@
import 'url:https://stats.aklinker1.io/umami.js';
console.log(browser.runtime.id);
logId();
console.log(2);
@@ -1,10 +0,0 @@
import '../../common/style.css';
export default defineContentScript({
matches: ['*://*/*'],
async main() {
console.log(browser.runtime.id);
logId();
mountContentScriptUi();
},
});
-3
View File
@@ -1,3 +0,0 @@
{
"extends": ["../tsconfig.base.json", "./src/.wxt/tsconfig.json"]
}
-17
View File
@@ -1,17 +0,0 @@
import { defineConfig } from 'wxt';
export default defineConfig({
srcDir: 'src',
storeIds: {
chrome: '123',
},
manifest: {
icons: {
'16': 'icon/16.png',
'32': 'icon/32.png',
'48': 'icon/48.png',
'96': 'icon/96.png',
'128': 'icon/128.png',
},
},
});
+2
View File
@@ -0,0 +1,2 @@
FROM lipanski/docker-static-website:latest
COPY dist .
@@ -0,0 +1,40 @@
<script lang="ts" setup>
const props = defineProps<{
patterns: Array<[intput: string, output: string]>;
}>();
</script>
<template>
<table class="no-vertical-dividers">
<thead>
<tr>
<th>Input Pattern</th>
<th></th>
<th>Output Path</th>
</tr>
</thead>
<tbody>
<tr v-for="pattern of patterns">
<td style="white-space: nowrap">
<code>entrypoints/{{ pattern[0] }}</code>
</td>
<td style="padding: 6px; opacity: 50%">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M4 11v2h12l-5.5 5.5l1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5L16 11H4Z"
/>
</svg>
</td>
<td style="white-space: nowrap">
<code>/{{ pattern[1] }}</code>
</td>
</tr>
</tbody>
</table>
</template>
@@ -0,0 +1,34 @@
<script lang="ts" setup>
import { ref, onMounted, computed } from 'vue';
const props = defineProps<{
tag?: string;
}>();
const examples = ref();
onMounted(async () => {
const res = await fetch(
'https://raw.githubusercontent.com/wxt-dev/wxt-examples/main/examples.json',
);
examples.value = await res.json();
});
const filteredExamples = computed(() => {
if (props.tag == null) return examples.value;
return examples.value.filter((example) => {
return example.tags?.includes(props.tag);
});
});
</script>
<template>
<ul>
<li v-if="examples == null">Loading...</li>
<template v-else>
<li v-for="example of filteredExamples">
<a :href="example.url" target="_blank">{{ example.name }}</a>
</li>
</template>
</ul>
</template>
+9 -7
View File
@@ -1,17 +1,19 @@
<script lang="ts" setup>
defineProps<{
import { computed } from 'vue';
const props = defineProps<{
name: string;
icon?: string;
}>();
const src = computed(() => {
if (props.icon) return props.icon;
return `https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/icons/${props.name.toLowerCase()}.svg`;
});
</script>
<template>
<img
:src="`https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/icons/${
name?.toLowerCase() ?? icon
}.svg`"
:alt="`${name} Logo`"
/>
<img :src="src" :alt="`${name} Logo`" />
</template>
<style scoped>
@@ -0,0 +1,229 @@
<script lang="ts" setup>
import { computed } from 'vue';
import useListExtensionDetails, {
ChromeExtension,
} from '../composables/useListExtensionDetails';
// Add extension IDs here. Order doesn't matter, will be sorted by weekly active users
// During the transition from chrome.google.com/webstore to
// chromewebstore.google.com, queue.wxt.dev might return null for your
// extension. If it does, use "<slug>/<id>" instead of just the ID. The slug
// can be retrieved from the URL of the item on chromewebstore.google.com
const chromeExtensionIds = [
'ocfdgncpifmegplaglcnglhioflaimkd', // GitHub: Better Line Counts
'mgmdkjcljneegjfajchedjpdhbadklcf', // Anime Skip Player
'bfbnagnphiehemkdgmmficmjfddgfhpl', // UltraWideo
'elfaihghhjjoknimpccccmkioofjjfkf', // StayFree - Website Blocker & Web Analytics
'okifoaikfmpfcamplcfjkpdnhfodpkil', // Doozy: Ai Made Easy
'lknmjhcajhfbbglglccadlfdjbaiifig', // tl;dv - Record, Transcribe & ChatGPT for Google Meet
'youtube中文配音/oglffgiaiekgeicdgkdlnlkhliajdlja', // Youtube中文配音
'agjnjboanicjcpenljmaaigopkgdnihi', // PreMiD
'aiakblgmlabokilgljkglggnpflljdgp', // Markdown Sticky Notes
'nomnkbngkijpffepcgbbofhcnafpkiep', // DocVersionRedirector
'ceicccfeikoipigeghddpocceifjelph', // Plex Skipper
'aelkipgppclpfimeamgmlonimflbhlgf', // GitHub Custom Notifier
'djnlaiohfaaifbibleebjggkghlmcpcj', // Fluent Read
'nhclljcpfmmaiojbhhnkpjcfmacfcian', // Facebook Video Controls
'mblkhbaakhbhiimkbcnmeciblfhmafna', // ElemSnap - Quick capture of webpage elements and conversion to images,
'oajalfneblkfiejoadecnmodfpnaeblh', // MS Edge TTS (Text to Speech)
'nedcanggplmbbgmlpcjiafgjcpdimpea', // YTBlock - Block any content from YouTube™
];
const { data, err, isLoading } = useListExtensionDetails(chromeExtensionIds);
const sortedExtensions = computed(() => {
if (!data.value?.length) return [];
return [...data.value]
.filter((item) => item != null)
.map((item) => ({
...item,
// Sort based on the user count weighted by the rating
sortKey: ((item.rating ?? 5) / 5) * item.weeklyActiveUsers,
}))
.filter((item) => !!item)
.sort((l, r) => r.sortKey - l.sortKey);
});
function getStoreUrl(extension: ChromeExtension) {
const url = new URL(extension.storeUrl);
url.searchParams.set('utm_source', 'wxt.dev');
return url.href;
}
</script>
<template>
<section class="vp-doc">
<div class="container">
<h2 id="whos-using-wxt">Who's Using WXT?</h2>
<p>
Battle tested and ready for production. Explore chrome extensions made
with WXT.
</p>
<p v-if="isLoading" style="text-align: center; opacity: 50%">
Loading...
</p>
<p
v-else-if="err || sortedExtensions.length === 0"
style="text-align: center; opacity: 50%"
>
Failed to load extension details.
</p>
<ul v-else>
<li
v-for="extension of sortedExtensions"
:key="extension.id"
class="relative"
>
<img
:src="extension.iconUrl"
:alt="`${extension.name} icon`"
referrerpolicy="no-referrer"
/>
<div class="relative">
<a
:href="getStoreUrl(extension)"
target="_blank"
:title="extension.name"
class="extension-name"
>{{ extension.name }}</a
>
<p class="description" :title="extension.shortDescription">
{{ extension.shortDescription }}
</p>
</div>
<p class="user-count">
<span>{{ extension.weeklyActiveUsers.toLocaleString() }} users</span
><template v-if="extension.rating != null"
>,
<span>{{ extension.rating }} stars</span>
</template>
</p>
</li>
</ul>
<p class="centered pr">
<a
href="https://github.com/wxt-dev/wxt/edit/main/docs/.vitepress/components/UsingWxtSection.vue"
target="_blank"
>Open a PR</a
>
to add your extension to the list!
</p>
</div>
</section>
</template>
<style scoped>
.vp-doc {
padding: 0 24px;
}
@media (min-width: 640px) {
.vp-doc {
padding: 0 48px;
}
}
@media (min-width: 960px) {
.vp-doc {
padding: 0 64px;
}
}
.container {
max-width: 1152px;
margin: 0 auto;
display: flex;
flex-direction: column;
}
li img {
width: 116px;
height: 116px;
padding: 16px;
border-radius: 8px;
background-color: var(--vp-c-default-soft);
}
ul {
display: grid;
grid-template-columns: repeat(1, 1fr);
align-items: stretch;
gap: 16px;
list-style: none;
margin: 16px 0;
padding: 0;
}
@media (min-width: 960px) {
ul {
grid-template-columns: repeat(2, 1fr);
}
}
li {
margin: 0 !important;
padding: 16px;
display: flex;
background-color: var(--vp-c-bg-soft);
border-radius: 12px;
flex: 1;
gap: 24px;
align-items: center;
}
.centered {
text-align: center;
}
li a,
li .user-count,
li .description {
padding: 0;
margin: 0;
}
li .user-count {
opacity: 70%;
font-size: small;
position: absolute;
bottom: 12px;
right: 16px;
}
li a {
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
cursor: pointer;
padding: 0;
margin: 0;
text-decoration: none;
}
li a:hover {
text-decoration: underline;
}
li div {
flex: 1;
}
li .description {
opacity: 90%;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
margin-bottom: 16px;
}
li .extension-name {
font-size: large;
}
.pr {
opacity: 70%;
}
.relative {
position: relative;
}
</style>
@@ -0,0 +1,59 @@
import { ref } from 'vue';
export interface ChromeExtension {
id: string;
name: string;
iconUrl: string;
weeklyActiveUsers: number;
shortDescription: string;
storeUrl: string;
rating: number | undefined;
}
const operationName = 'WxtDocsUsedBy';
const query = `query ${operationName}($ids:[String!]!) {
chromeExtensions(ids: $ids) {
id
name
iconUrl
weeklyActiveUsers
shortDescription
storeUrl
rating
}
}`;
export default function (ids: string[]) {
const data = ref<ChromeExtension[]>();
const err = ref<unknown>();
const isLoading = ref(true);
fetch('https://queue.wxt.dev/api', {
method: 'POST',
body: JSON.stringify({
operationName,
query,
variables: { ids },
}),
})
.then(async (res) => {
isLoading.value = false;
const {
data: { chromeExtensions },
} = await res.json();
data.value = chromeExtensions;
err.value = undefined;
})
.catch((error) => {
isLoading.value = false;
console.error(error);
data.value = undefined;
err.value = error;
});
return {
data,
err,
isLoading,
};
}
+119 -36
View File
@@ -1,72 +1,155 @@
import { defineConfig } from 'vitepress';
import { DefaultTheme, defineConfig } from 'vitepress';
import { generateCliDocs } from './plugins/generate-cli-docs';
import typedocSidebar from '../api/typedoc-sidebar.json';
const filteredTypedocSidebar = typedocSidebar.filter(
(item) => item.text !== 'API',
);
// Typedoc's markdown theme adds collapse: true to all our items, event ones without any children,
// so they need to be removed.
function removeCollapsedWithNoItems(items: DefaultTheme.SidebarItem[]) {
for (const item of items) {
if (item.items) removeCollapsedWithNoItems(item.items);
else delete item.collapsed;
}
}
removeCollapsedWithNoItems(filteredTypedocSidebar);
const title = 'Next-gen Web Extension Framework';
const titleSuffix = ' WXT';
const description =
"WXT provides the best developer experience, making it quick, easy, and fun to develop chrome extensions for all browsers. With built-in utilities for building, zipping, and publishing your extension, it's easy to get started.";
const ogTitle = `${title}${titleSuffix}`;
const ogUrl = 'https://wxt.dev';
const ogImage = 'https://wxt.dev/social-preview.png';
// https://vitepress.dev/reference/site-config
export default defineConfig({
titleTemplate: `:title${titleSuffix}`,
title: 'WXT',
description: 'Next gen framework for developing web extensions',
description,
vite: {
clearScreen: false,
plugins: [generateCliDocs()],
},
lastUpdated: true,
sitemap: {
hostname: 'https://wxt.dev',
},
head: [
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:title', content: ogTitle }],
['meta', { property: 'og:image', content: ogImage }],
['meta', { property: 'og:url', content: ogUrl }],
['meta', { property: 'og:description', content: description }],
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
[
'script',
{
async: '',
'data-website-id': 'c1840c18-a12c-4a45-a848-55ae85ef7915',
src: 'https://umami.aklinker1.io/script.js',
},
],
],
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
// logo: '/logo.svg',
logo: {
src: '/logo.svg',
alt: 'WXT logo',
},
editLink: {
pattern: 'https://github.com/aklinker1/wxt/edit/main/docs/:path',
pattern: 'https://github.com/wxt-dev/wxt/edit/main/docs/:path',
},
search: {
provider: 'local',
},
nav: [
{ text: 'Get Started', link: '/get-started/installation.md' },
{ text: 'Guide', link: '/guide/auto-imports.md' },
{ text: 'Config', link: '/config.md' },
{ text: 'API', link: '/api.md' },
{ text: 'Guide', link: '/guide/installation.md' },
{ text: 'Entrypoints', link: '/entrypoints/background.md' },
{ text: 'Examples', link: '/examples.md' },
{ text: 'API', link: '/api/cli.md' },
],
sidebar: {
'/get-started/': [
{
text: 'Get Started',
items: [
{ text: 'Introduction', link: '/get-started/introduction.md' },
{ text: 'Installation', link: '/get-started/installation.md' },
{ text: 'Configuration', link: '/get-started/configuration.md' },
{ text: 'Entrypoints', link: '/get-started/entrypoints.md' },
{ text: 'Assets', link: '/get-started/assets.md' },
{ text: 'Build Targets', link: '/get-started/build-targets.md' },
{ text: 'Publishing', link: '/get-started/publishing.md' },
{ text: 'Testing', link: '/get-started/testing.md' },
],
},
],
'/guide/': [
{
text: 'Guide',
items: [
{ text: 'Auto-imports', link: '/guide/auto-imports.md' },
{ text: 'Introduction', link: '/guide/introduction.md' },
{ text: 'Installation', link: '/guide/installation.md' },
{ text: 'Configuration', link: '/guide/configuration.md' },
{ text: 'Entrypoints', link: '/guide/entrypoints.md' },
{ text: 'Manifest.json', link: '/guide/manifest.md' },
{ text: 'Extension APIs', link: '/guide/extension-apis.md' },
{ text: 'Storage', link: '/guide/storage.md' },
{ text: 'Assets', link: '/guide/assets.md' },
{ text: 'Content Script UI', link: '/guide/content-script-ui.md' },
{ text: 'Multiple Browsers', link: '/guide/multiple-browsers.md' },
{ text: 'ES Modules', link: '/guide/esm.md' },
{ text: 'Auto-imports', link: '/guide/auto-imports.md' },
{ text: 'Vite', link: '/guide/vite.md' },
{ text: 'Remote Code', link: '/guide/remote-code.md' },
{ text: 'Publishing', link: '/guide/publishing.md' },
{ text: 'Handling Updates', link: '/guide/handling-updates.md' },
{ text: 'Development', link: '/guide/development.md' },
{ text: 'Testing', link: '/guide/testing.md' },
],
},
{
text: 'Other',
items: [
{ text: 'Migrate to WXT', link: '/guide/migrate-to-wxt.md' },
{ text: 'Compare', link: '/guide/compare.md' },
],
},
],
'/entrypoints/': [
{
text: 'Entrypoints',
items: [
{ text: 'Background', link: '/guide/background.md' },
{ text: 'Bookmarks', link: '/guide/bookmarks.md' },
{ text: 'Content Scripts', link: '/guide/content-scripts.md' },
{ text: 'Devtools', link: '/guide/devtools.md' },
{ text: 'History', link: '/guide/history.md' },
{ text: 'Newtab', link: '/guide/newtab.md' },
{ text: 'Options', link: '/guide/options.md' },
{ text: 'Popup', link: '/guide/popup.md' },
{ text: 'Sandbox', link: '/guide/sandbox.md' },
{ text: 'Unlisted Pages', link: '/guide/unlisted-pages.md' },
{ text: 'Unlisted Scripts', link: '/guide/unlisted-scripts.md' },
{ text: 'Background', link: '/entrypoints/background.md' },
{ text: 'Bookmarks', link: '/entrypoints/bookmarks.md' },
{
text: 'Content Scripts',
link: '/entrypoints/content-scripts.md',
},
{ text: 'CSS', link: '/entrypoints/css.md' },
{ text: 'Devtools', link: '/entrypoints/devtools.md' },
{ text: 'History', link: '/entrypoints/history.md' },
{ text: 'Newtab', link: '/entrypoints/newtab.md' },
{ text: 'Options', link: '/entrypoints/options.md' },
{ text: 'Popup', link: '/entrypoints/popup.md' },
{ text: 'Sandbox', link: '/entrypoints/sandbox.md' },
{ text: 'Side Panel', link: '/entrypoints/sidepanel.md' },
{ text: 'Unlisted Pages', link: '/entrypoints/unlisted-pages.md' },
{
text: 'Unlisted Scripts',
link: '/entrypoints/unlisted-scripts.md',
},
].sort((l, r) => l.text.localeCompare(r.text)),
},
],
'/api/': [
{
items: [
{ text: 'CLI', link: '/api/cli.md' },
{
text: 'Modules',
items: filteredTypedocSidebar,
},
],
},
],
},
socialLinks: [{ icon: 'github', link: 'https://github.com/aklinker1/wxt' }],
socialLinks: [
{ icon: 'discord', link: 'https://discord.gg/ZFsZqGery9' },
{ icon: 'github', link: 'https://github.com/wxt-dev/wxt' },
],
},
});
+5
View File
@@ -0,0 +1,5 @@
# CLI Reference
> Reference generated from `wxt <command> --help`
{{ DOCS }}
@@ -0,0 +1,118 @@
import { relative, resolve } from 'node:path';
import { readFileSync, writeFileSync } from 'node:fs';
import { format } from 'prettier';
import consola from 'consola';
import { execaCommand } from 'execa';
let hasGenerated = false;
const cliDir = resolve('packages/wxt/src/cli/commands');
const cliDirGlob = resolve(cliDir, '**');
const cliTemplatePath = resolve('docs/.vitepress/plugins/cli.tpl.md');
const cliPath = resolve('docs/api/cli.md');
const PREFACE = `<!--
DO NOT EDIT
Generated by \`wxt/docs/.vitepress/plugins/generate-config-docs.ts\`
To make changes to the config reference, update the JSDoc in \`src/core/types/external.ts\`.
-->`;
export function generateCliDocs() {
writeFileSync(cliPath, '');
const generateDocs = async () => {
consola.info(`Generating ${relative(process.cwd(), cliPath)}`);
try {
const res = await execaCommand('pnpm -s wxt --help', {
cwd: 'packages/wxt',
});
const dev = splitInfo(res.stdout);
const lines: Array<string | string[]> = [
`## \`wxt\``,
'```sh',
dev.rest,
'```',
];
const commands = await Promise.allSettled(
extractCommands(dev.info).map(async (command) => {
const res = await execaCommand(`pnpm -s wxt ${command} --help`, {
cwd: 'packages/wxt',
});
const { rest: docs } = splitInfo(res.stdout);
return [`## \`wxt ${command}\``, '```sh', docs, '```'];
}),
);
lines.push(
...commands
.filter((res) => res.status === 'fulfilled')
.map(
(res) => (res as unknown as PromiseFulfilledResult<string>).value,
),
);
const text = await format(
PREFACE +
'\n\n' +
readFileSync(cliTemplatePath, 'utf-8').replace(
'{{ DOCS }}',
lines.flat().join('\n'),
),
{ parser: 'markdown' },
);
writeFileSync(cliPath, text);
consola.success(`Generated ${relative(process.cwd(), cliPath)}`);
} catch (err) {
consola.fail(`Failed to generate ${relative(process.cwd(), cliPath)}`);
consola.error(err.message);
}
};
return {
name: 'docs:generate-cli-docs',
async config() {
if (!hasGenerated) {
hasGenerated = true;
await generateDocs();
}
},
configureServer(server: any) {
server.watcher.add(cliDirGlob);
},
async handleHotUpdate(ctx: { file: string }) {
if (ctx.file === cliTemplatePath || ctx.file.includes(cliDir)) {
await generateDocs();
}
},
};
}
function splitInfo(text: string): { info: string; rest: string } {
const infoStart = text.indexOf('For more info,');
const infoEnd = text.indexOf('\n\nOptions:');
if (infoStart === -1 || infoEnd === -1) {
return { info: '', rest: text };
}
const info = text.substring(infoStart, infoEnd).trim();
const rest = text.replace(info, '').trim().replace('\n\n\n\n', '\n\n');
return { info, rest };
}
function extractCommands(info: string): string[] {
const commands: string[] = [];
// Split the info by line and iterate through each line
info.split('\n').forEach((line) => {
// Use regex to capture the command after "$ wxt " and before "--help"
const match = line.match(/\$ wxt (\w+) --help/);
if (match && match[1]) {
commands.push(match[1]);
}
});
return commands;
}
+77
View File
@@ -0,0 +1,77 @@
/* Colors */
:root {
--wxt-c-green: #53bc4a;
--wxt-c-green-1: #67d45e;
--wxt-c-green-2: #4fa048;
--wxt-c-green-3: #447e3f;
}
/* https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css */
:root {
--vp-c-brand: var(--wxt-c-green);
--vp-c-brand-1: var(--wxt-c-green-1);
--vp-c-brand-2: var(--wxt-c-green-2);
--vp-c-brand-3: var(--wxt-c-green-3);
--vp-button-brand-bg: var(--wxt-c-green);
--vp-button-brand-hover-bg: var(--wxt-c-green-2);
--vp-button-brand-active-bg: var(--wxt-c-green-3);
--vp-code-link-color: var(--wxt-c-green);
/* --vp-c-text-1: var(--wxt-c-green-1); */
--vp-button-brand-text: var(--vp-c-black);
--vp-button-brand-hover-text: var(--vp-c-black);
--vp-button-brand-active-text: var(--vp-c-black);
--vp-custom-block-tip-border: var(--wxt-c-green);
--vp-custom-block-tip-text: var(--wxt-c-green);
/* --vp-code-block-bg: #222422;
--vp-code-copy-code-bg: #313431;
--vp-code-copy-code-hover-bg: #3c403c; */
--vp-custom-block-tip-bg: var(--vp-code-block-bg);
--vp-custom-block-info-bg: var(--vp-code-block-bg);
--vp-code-color: #476582;
}
.vp-doc a {
color: var(--wxt-c-green);
}
.dark {
--vp-c-bg: #131413;
--vp-c-bg-soft: #1a1b1a;
--vp-c-bg-soft-up: #1f201f;
--vp-c-bg-soft-down: #262926;
--vp-c-bg-soft-mute: #242424;
--vp-c-bg-alt: #171817;
--vp-c-default: #313136;
--vp-c-default-1: #3a3a3c;
--vp-c-default-2: #505053;
--vp-c-default-3: #2c2c30;
--vp-c-default-soft: #252529;
--vp-code-block-bg: #191a19;
--vp-code-copy-code-bg: #212321;
--vp-code-copy-code-hover-bg: #292d29;
--vp-custom-block-info-bg: #191a19;
--vp-code-color: #c9def1;
}
.vp-doc .no-vertical-dividers th,
.vp-doc .no-vertical-dividers td {
border: none;
}
.vp-doc .no-vertical-dividers tr {
border: 1px solid var(--vp-c-divider);
}
+7
View File
@@ -1,9 +1,16 @@
import DefaultTheme from 'vitepress/theme';
import Icon from '../components/Icon.vue';
import EntrypointPatterns from '../components/EntrypointPatterns.vue';
import UsingWxtSection from '../components/UsingWxtSection.vue';
import ExampleList from '../components/ExampleList.vue';
import './custom.css';
export default {
extends: DefaultTheme,
enhanceApp(ctx) {
ctx.app.component('Icon', Icon);
ctx.app.component('EntrypointPatterns', EntrypointPatterns);
ctx.app.component('UsingWxtSection', UsingWxtSection);
ctx.app.component('ExampleList', ExampleList);
},
};
-5
View File
@@ -1,5 +0,0 @@
# API Reference
:::warning 🚧&ensp;Under construction
This documentation does not exist yet.
:::
Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 KiB

After

Width:  |  Height:  |  Size: 238 KiB

-5
View File
@@ -1,5 +0,0 @@
# Config
:::warning 🚧&ensp;Under construction
This documentation does not exist yet.
:::
@@ -6,12 +6,17 @@ For MV2, the background is added as a script to the background page. For MV3, th
## Filenames
`entrypoints/background.ts` is the only recoginzed filename for the background script.
<EntrypointPatterns
:patterns="[
['background.[jt]s', 'background.js'],
['background/index.[jt]s', 'background.js'],
]"
/>
## Definition
:::warning
The main function of the background **_CANNOT BE ASYNC_**. Event listeners must be added syncronously on background startup. If your main function returns a promise, WXT will log an error.
The main function of the background **_CANNOT BE ASYNC_**. Event listeners must be added synchronously on background startup. If your main function returns a promise, WXT will log an error.
:::
```ts
@@ -28,6 +33,10 @@ export default defineBackground({
persistent: undefined | true | false,
type: undefined | 'module',
// Set include/exclude if the background should be removed from some builds
include: undefined | string[],
exclude: undefined | string[],
// Executed when background is loaded
main() {
// ...
@@ -4,20 +4,25 @@
## Filenames
- `entrypoints/bookmarks.html`
- `entrypoints/bookmarks/index.html`
<EntrypointPatterns
:patterns="[
['bookmarks.html', 'bookmarks.html'],
['bookmarks/index.html', 'bookmarks.html'],
]"
/>
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
+107
View File
@@ -0,0 +1,107 @@
# Content Scripts
[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/content_scripts/) &bull; [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts)
When creating content script entrypoints, they are automatically included in the `manifest.json` along with any CSS files they import.
## Filenames
<EntrypointPatterns
:patterns="[
['content.[jt]sx?', 'content-scripts/content.js'],
['content/index.[jt]sx?', 'content-scripts/content.js'],
['<name>.content.[jt]sx?', 'content-scripts/<name>.js'],
['<name>.content/index.[jt]sx?', 'content-scripts/<name>.js'],
]"
/>
## Definition
```ts
export default defineContentScript({
// Set manifest options
matches: string[],
excludeMatches: undefined | [],
includeGlobs: undefined | [],
excludeGlobs: undefined | [],
allFrames: undefined | [],
runAt: undefined | 'document_start' | 'document_end' | 'document_idle',
matchAboutBlank: undefined | true | false,
matchOriginAsFallback: undefined | true | false,
world: undefined | 'ISOLATED' | 'MAIN',
// Set include/exclude if the background should be removed from some builds
include: undefined | string[],
exclude: undefined | string[],
// Configure how CSS is injected onto the page
cssInjectionMode: undefined | "manifest" | "manual" | "ui",
// Configure how/when content script will be registered
registration: undefined | "manifest" | "runtime",
main(ctx: ContentScriptContext) {
// Executed when content script is loaded
},
});
```
> All manifest options default to `undefined`.
When defining multiple content scripts, content script entrypoints that have the same set of options will be merged into a single `content_script` item in the manifest.
## CSS
To include CSS with your content script, import the CSS file at the top of your entrypoint.
```
<srcDir>/
└─ entrypoints/
└─ overlay.content/
├─ index.ts
└─ style.css
```
```ts
// entrypoints/overlay.content/index.ts
import './style.css';
export default defineContentScript({
matches: ['*://google.com/*', '*://duckduckgo.com/*'],
main(ctx) {
// ...
},
});
```
Any styles imported in your content script will be added to that content script's `css` array in your `manifest.json`:
```json
// .output/chrome-mv3/manifest.json
{
"content_scripts": [
{
"matches": ["*://google.com/*", "*://duckduckgo.com/*"],
"js": ["content-scripts/overlay.js"],
"css": ["content-scripts/overlay.css"]
}
]
}
```
To disable this behavior, set `cssInjectionMode` to `"manual"` or `"ui"`.
```ts
export default defineContentScript({
matches: ['*://google.com/*', '*://duckduckgo.com/*'],
cssInjectionMode: 'manual',
main(ctx) {
// ...
},
});
```
See [Content Script UI](/guide/content-script-ui) for more info on creating UIs and including CSS in content scripts.
+44
View File
@@ -0,0 +1,44 @@
# CSS
WXT can build CSS entrypoints individually. CSS entrypoints are always unlisted.
See [Content Script CSS](/entrypoints/content-scripts#css) documentation for the recommended approach to include CSS with a content script.
:::info
If the recommended approach doesn't work for your use case, you can use any of the filename patterns below to build the styles separate from the JS and use the [`transformManifest` hook](/api/wxt/interfaces/InlineConfig#transformmanifest) to manually add your CSS file to the manifest.
:::
## Filenames
<EntrypointPatterns
:patterns="[
['<name>.(css|scss|sass|less|styl|stylus)', '<name>.css'],
['<name>/index.(css|scss|sass|less|styl|stylus)', '<name>.css'],
['content.(css|scss|sass|less|styl|stylus)', 'content-scripts/content.css'],
['content/index.(css|scss|sass|less|styl|stylus)', 'content-scripts/content.css'],
['<name>.content.(css|scss|sass|less|styl|stylus)', 'content-scripts/<name>.css'],
['<name>.content/index.(css|scss|sass|less|styl|stylus)', 'content-scripts/<name>.css'],
]"
/>
## Definition
```css
body {
/* Plain CSS file */
}
```
Follow Vite's guide to setup a preprocessor: https://vitejs.dev/guide/features.html#css-pre-processors
```sh
pnpm i sass
```
```scss
body {
h1 {
/* ...*/
}
}
```
+40
View File
@@ -0,0 +1,40 @@
# Devtools
[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/devtools/) &bull; [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/devtools_page)
## Filenames
<EntrypointPatterns
:patterns="[
['devtools.html', 'devtools.html'],
['devtools/index.html', 'devtools.html'],
]"
/>
## Definition
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
</body>
</html>
```
## Adding UI Elements
Chrome extensions allow you to add panels and side panes to the devtools window.
![DevTools window showing Elements panel and Styles sidebar pane.](https://developer.chrome.com/static/docs/extensions/how-to/devtools/extend-devtools/image/devtools-window-showing-e-9051f7f0347cd_1920.png)
See the WXT's examples for a full walkthrough of extending the devtools window:
<ExampleList tag="devtools" />
@@ -4,20 +4,25 @@
## Filenames
- `entrypoints/history.html`
- `entrypoints/history/index.html`
<EntrypointPatterns
:patterns="[
['history.html', 'history.html'],
['history/index.html', 'history.html'],
]"
/>
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
@@ -4,20 +4,25 @@
## Filenames
- `entrypoints/newtab.html`
- `entrypoints/newtab/index.html`
<EntrypointPatterns
:patterns="[
['newtab.html', 'newtab.html'],
['newtab/index.html', 'newtab.html'],
]"
/>
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
@@ -4,15 +4,17 @@
## Filenames
- `entrypoints/options.html`
- `entrypoints/options/index.html`
<EntrypointPatterns
:patterns="[
['options.html', 'options.html'],
['options/index.html', 'options.html'],
]"
/>
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
@@ -21,6 +23,9 @@ Plain old HTML file.
<meta name="manifest.open_in_tab" content="true|false" />
<meta name="manifest.chrome_style" content="true|false" />
<meta name="manifest.browser_style" content="true|false" />
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
@@ -4,15 +4,17 @@
## Filenames
- `entrypoints/popup.html`
- `entrypoints/popup/index.html`
<EntrypointPatterns
:patterns="[
['popup.html', 'popup.html'],
['popup/index.html', 'popup.html'],
]"
/>
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
@@ -27,6 +29,10 @@ Plain old HTML file.
}"
/>
<meta name="manifest.type" content="page_action|browser_action" />
<meta name="manifest.browser_style" content="true|false" />
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
+37
View File
@@ -0,0 +1,37 @@
# Sandbox
[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/manifest/sandbox/)
:::tip Chromium Only
Firefox does not support sandboxed pages.
:::
## Filenames
<EntrypointPatterns
:patterns="[
['sandbox.html', 'sandbox.html'],
['sandbox/index.html', 'sandbox.html'],
['<name>.sandbox.html', '<name>.html` '],
['<name>.sandbox/index.html', '<name>.html` '],
]"
/>
## Definition
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
</body>
</html>
```
+49
View File
@@ -0,0 +1,49 @@
# Side Panel
[Chrome Docs](https://developer.chrome.com/docs/extensions/reference/sidePanel/) &bull; [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars)
In Chrome, side panels use the "side_panel" API, while Firefox uses the "sidebar_action" API.
:::warning
Chrome added support for sidepanels in Manifest V3, they are not available in Manifest V2.
:::
## Filenames
<EntrypointPatterns
:patterns="[
['sidepanel.html', 'sidepanel.html'],
['sidepanel/index.html', 'sidepanel.html'],
['<name>.sidepanel.html', '<name>.html` '],
['<name>.sidepanel/index.html', '<name>.html` '],
]"
/>
## Definition
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Default Side Panel Title</title>
<meta
name="manifest.default_icon"
content="{
16: '/icon-16.png',
24: '/icon-24.png',
...
}"
/>
<meta name="manifest.open_at_install" content="true|false" />
<meta name="manifest.browser_style" content="true|false" />
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
</body>
</html>
```
+49
View File
@@ -0,0 +1,49 @@
# Unlisted Pages
HTML pages that are bundled and shipped with the extension, but are not included in the manifest.
If you plan on using the page in an iframe, don't forget to add the page to [`web_accessible_resources`](https://developer.chrome.com/docs/extensions/reference/manifest/web-accessible-resources).
### Examples
- Onboarding
- Dashboard
- FAQ
- Help
- Changelog
## Filenames
<EntrypointPatterns
:patterns="[
['<name>.html', '<name>.html'],
['<name>/index.html', '<name>.html'],
]"
/>
Pages are accessible at `'/<name>.html'`:
```ts
const url = browser.runtime.getURL('/<name>.html');
console.log(url); // "chrome-extension://<id>/<name>.html"
```
## Definition
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
<!-- Set include/exclude if the page should be removed from some builds -->
<meta name="manifest.include" content="['chrome', ...]" />
<meta name="manifest.exclude" content="['chrome', ...]" />
</head>
<body>
<!-- ... -->
</body>
</html>
```
+37
View File
@@ -0,0 +1,37 @@
# Unlisted Scripts
TypeScript files that are bundled and shipped with the extension, but are not included in the manifest.
You are responsible for loading/running these scripts where needed. If necessary, don't forget to add the script and/or any related stylesheets to [`web_accessible_resources`](https://developer.chrome.com/docs/extensions/reference/manifest/web-accessible-resources).
## Filenames
<EntrypointPatterns
:patterns="[
['<name>.[jt]sx?', '<name>.js'],
['<name>/index.[jt]sx?', '<name>.js'],
]"
/>
## Definition
```ts
export default defineUnlistedScript(() => {
// Executed when script is loaded
});
```
or
```ts
export default defineUnlistedScript({
// Set include/exclude if the script should be removed from some builds
include: undefined | string[],
exclude: undefined | string[],
// Executed when script is loaded
main() {
// ...
},
});
```
+7
View File
@@ -0,0 +1,7 @@
# Examples
Simple walkthroughs to accomplish common tasks or patterns with WXT.
<ExampleList />
> Full code available at [`wxt-dev/wxt-examples`](https://github.com/wxt-dev/wxt-examples)
-46
View File
@@ -1,46 +0,0 @@
# Build Targets
You can build an extension for any combination of browser and manifest verison. Different browsers and manifest versions support different APIs and entrypoints, so be sure to check that your extension functions as expected for each target.
Separate build targets are written to their own output directories:
```
<root>
└─ .output
├─ chrome-mv3
├─ firefox-mv2
├─ edge-mv3
└─ ...
```
## Target Browser
To build for a specific browser, pass the `-b --browser` flag from the CLI:
```
wxt --browser firefox
wxt build --browser firefox
```
By default, it will build for `chrome`. When excluding the [`--mv2` or `--mv3` flags](#target-manifest-version), it will default to the commonly accepted manifest version used with that browser.
| Browser | Default Manifest Version |
| ---------------- | :----------------------: |
| `chrome` | 3 |
| `firefox` | 2 |
| `safari` | 2 |
| `edge` | 3 |
| Any other string | 3 |
## Target Manifest Version
To build for a specific manifest version, pass either the `--mv2` flag or `--mv3` flag from the CLI.
```sh
wxt --mv2
wxt build --mv2
```
When the `-b --browser` flag is not passed, it defaults to `chrome`. So here, we're targetting MV2 for Chrome.
-89
View File
@@ -1,89 +0,0 @@
# Defining Entrypoints
An entrypoints is any HTML, JS, or CSS file that needs to be bundled and included with the extension.
They may or may not be listed in the extension's `manifest.json`.
## `/entrypoints` Directory
In WXT, entrypoints are defined by adding a file to the `entrypoints/` directory.
For example, a project that looks like this:
```
<root>
├─ entrypoints/
│ ├─ background.ts
│ ├─ content.ts
│ ├─ injected.ts
│ └─ popup.html
└─ wxt.config.ts
```
would result in the following `manifest.json`:
```json
{
// ...
"manifest_version": 3,
"action": {
// ...
"default_popup": "popup.html"
},
"background": {
// ...
"service_worker": "background.js"
},
"content_scripts": [
{
// ...
"js": ["content-scripts/content.js"]
}
]
}
```
If a file uses a [special name recognized by WXT](/get-started/entrypoints.md), it will be added to the manifest. In this case:
- `popup.html` &rarr; `action.default_popup`
- `content.ts` &rarr; `content_scripts.0.js.0`
- `background.ts` &rarr; `background.service_worker`
But not all entrypoints are added to the `manifest.json`. If they have a name that is not recognized by WXT, they are still built and included in the extension, but they are considered "unlisted" and are not apart of the manifest.
In this case, `injected.ts` gets bundled to `<outdir>/injected.js` and is accessible via `browser.runtime.getURL("/injected.js")`.
:::info
See [`/entrypoints` folder](/guide/background.md) documentation for a full list of recognized entrypoint filenames.
:::
## Entrypoint Options
Some entrypoints, like content scripts, actions, or the background, can recieve additional options.
In HTML files, options are listed as `meta` tags:
```html
<html>
<head>
<!-- Defining the popup's "default_icon" field -->
<meta name="manifest.default_icon" content="{ '16': '/icon/16.png' }" />
</head>
</html>
```
In TS files, options are apart of the file's default export:
```ts
export default defineContentScript({
matches: ['*://*.google.com/*'],
runAt: 'document_start',
main() {
// ...
},
});
```
:::info
For a full list of entrypoints and each of their options, see the [`/entrypoints` folder](/guide/background.md) documentation.
:::
-130
View File
@@ -1,130 +0,0 @@
# Installation
Bootstrap a new project or start from scratch.
## Bootstrap Project
:::warning 🚧&ensp;The `wxt init` command is not implemented yet.
See [From Scratch](#from-scratch) or reference one of the templates below.
:::
:::code-group
```sh [pnpm]
pnpx wxt@latest init
```
```sh [npm]
npx wxt@latest init
```
:::
There are several starting templates available.
| TypeScript |
| ---------------------------------------------------------------------------------------------------- |
| <Icon name="TypeScript" /> [`vanilla`](https://github.com/aklinker1/wxt/tree/main/templates/vanilla) |
| <Icon name="Vue" /> [`vue`](https://github.com/aklinker1/wxt/tree/main/templates/vue) |
| <Icon name="React" /> [`react`](https://github.com/aklinker1/wxt/tree/main/templates/react) |
| <Icon name="Svelte" /> [`svelte`](https://github.com/aklinker1/wxt/tree/main/templates/svelte) |
> All templates are in TypeScript. WXT does not support JS at this time.
## From Scratch
Create a new NPM project:
:::code-group
```sh [pnpm]
mkdir project-name
cd project-name
pnpm init
echo 'shamefully-hoist=true' >> .npmrc
```
```sh [npm]
mkdir project-name
cd project-name
npm init
```
```sh [yarn]
mkdir project-name
cd project-name
yarn init
```
:::
Then install `wxt`:
:::code-group
```sh [pnpm]
pnpm add wxt
```
```sh [npm]
npm i --save wxt
```
```sh [yarn]
yarn add wxt
```
:::
Add your first entrypoint:
```ts
// entrypoints/background.ts
export default defineBackground(() => {
console.log(`Hello from ${browser.runtime.id}!`);
});
```
Finally, add scripts to your `package.json`:
```json
{
"scripts": {
"dev": "wxt", // [!code ++]
"dev:firefox": "wxt --browser firefox", // [!code ++]
"build": "wxt build", // [!code ++]
"build:firefox": "wxt build --browser firefox", // [!code ++]
"postinstall": "wxt prepare" // [!code ++]
}
}
```
> You can skip `*:firefox` scripts if you don't want to support Firefox
## 🚧 WSL Support
**_WXT does not support [Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/) yet_**. See [Issue #55](https://github.com/aklinker1/wxt/issues/55) to track progress.
In the meantime, you can use `cmd` instead.
## Development
Once you've installed WXT, you can start the development server using the `dev` script.
```sh
pnpm dev
```
:::tip 🎉&ensp;Well done!
The dev command will build the extension for development, open the browser, and reload the different parts of the extension when you save changes.
:::
## Next Steps
You're ready to build a out your web extension!
- Learn how to [add entrypoints](./entrypoints.md) like the popup, background, or content scripts
- [Configure WXT](./configuration.md) by creating a `wxt.config.ts` file
-5
View File
@@ -1,5 +0,0 @@
# Publishing
:::warning 🚧&ensp;Not implemented yet!
For now, manually zip the output directory and upload to stores by hand.
:::
-5
View File
@@ -1,5 +0,0 @@
# Testing
:::warning 🚧&ensp;Testing utils are not implemented yet!
Eventually, the plan is to have an integration with Vitest.
:::
@@ -63,7 +63,7 @@ Files in the assets directory will be processed by Vite. They are imported in yo
<!-- ... -->
</head>
<body>
<img src="~/illustration.svg" />
<img src="~/assets/illustration.svg" />
<!-- ... -->
</body>
</html>
+25 -11
View File
@@ -3,27 +3,41 @@
WXT uses the same tool as Nuxt for auto-imports, [`unimport`](https://github.com/unjs/unimport).
:::info Testing
To setup your test environment for auto-imports, see [Testing](/get-started/testing.md).
To setup your test environment for auto-imports, see [Testing](/guide/testing).
:::
## WXT Auto-imports
Some WXT APIs can be used without importing them:
- [`browser`](/config.md#browser) from `wxt/browser`, a small wrapper around `webextension-polyfill`
- [`defineContentScript`](/config.md#defiencontentscript) from `wxt/client`
- [`defineBackground`](/config.md#definebackgroundscript) from `wxt/client`
- [`browser`](/api/wxt/browser/variables/browser) from `wxt/browser`, a small wrapper around `webextension-polyfill`
- [`defineContentScript`](/api/wxt/sandbox/functions/defineContentScript) from `wxt/sandbox`
- [`defineBackground`](/api/wxt/sandbox/functions/defineBackground) from `wxt/sandbox`
- [`defineUnlistedScript`](/api/wxt/sandbox/functions/defineUnlistedScript) from `wxt/sandbox`
- [`createIntegratedUi`](/api/wxt/client/functions/createIntegratedUi) from `wxt/client`
- [`createShadowRootUi`](/api/wxt/client/functions/createShadowRootUi) from `wxt/client`
- [`createIframeUi`](/api/wxt/client/functions/createIframeUi) from `wxt/client`
- [`fakeBrowser`](/api/wxt/testing/variables/fakeBrowser) from `wxt/testing`
And more. All [`wxt/client`](/config.md#wxtclient) APIs can be used without imports.
And more!
## Project Auto-imports
In addition WXT APIs, default and named exports from inside the following directories can be used without listing them in imports.
- `<srcDir>/components/**/*`
- `<srcDir>/composables/**/*`
- `<srcDir>/hooks/**/*`
- `<srcDir>/utils/**/*`
- `<srcDir>/components/*`
- `<srcDir>/composables/*`
- `<srcDir>/hooks/*`
- `<srcDir>/utils/*`
To add auto-imports from subdirectories, like `utils/api/some-file.ts`, re-export them from the base directory:
```ts
// utils/index.ts
export * from './api/some-file.ts';
```
Alternatively, you could add the directory to the list of auto-import directories in your config file.
## TypeScript
@@ -51,8 +65,8 @@ import { defineConfig } from 'wxt';
export default defineConfig({
imports: {
// Add auto-imports for vue fuctions like createApp, ref, computed, watch, toRaw, etc...
preset: ['vue'],
// Add auto-imports for vue functions like createApp, ref, computed, watch, toRaw, etc...
presets: ['vue'],
},
});
```
+50
View File
@@ -0,0 +1,50 @@
# Compare
Lets compare the features of WXT vs [Plasmo](https://docs.plasmo.com/framework) (another web extension framework) and [CRXJS](https://crxjs.dev/vite-plugin) (the most popular bundler plugin).
## Overview
| Features | WXT | Plasmo | CRXJS |
| ---------------------------------------------------- | :-------------------------: | :--------------------------------------: | :---------------------------------------------------------------------: |
| Supports all browsers | ✅ | ✅ | ❌ See [#56](https://github.com/crxjs/chrome-extension-tools/issues/56) |
| MV2 Support | ✅ | ✅ | 🟡 Either MV2 or MV3 |
| MV3 Support | ✅ | ✅ | 🟡 Either MV2 or MV3 |
| Create Extension ZIPs | ✅ | ✅ | ❌ |
| Create Firefox Sources ZIP | ✅ | ❌ | ❌ |
| First-class TypeScript support | ✅ | ✅ | ✅ |
| Entrypoint discovery | File based | File based | ❌ |
| Inline entrypoint config | ✅ | ✅ | Manifest based |
| Auto-imports | ✅ | ❌ | ❌ |
| Supports all frontend frameworks | ✅ | 🟡 Only React, Vue, and Svelte | ✅ |
| Framework specific entrypoints (like `Popup.tsx`) | 🟡 `.html` `.ts` `.tsx` | ✅ `.html` `.ts` `.tsx` `.vue` `.svelte` | ❌ |
| Automated publishing | ✅ | ✅ | ❌ |
| Remote Code Bundling (Google Analytics) | ✅ | ✅ | ❌ |
| <strong style="opacity: 50%">Dev Mode</strong> | | |
| `.env` Files | ✅ | ✅ | ✅ |
| Opens browser and install extension | ✅ | ❌ | ❌ |
| HMR for UIs | ✅ | 🟡 React only | ✅ |
| Reload HTML Files on Change | ✅ | 🟡 Reloads entire extension | ✅ |
| Reload Content Scripts on Change | ✅ | 🟡 Reloads entire extension | ✅ |
| Reload Background on Change | 🟡 Reloads entire extension | 🟡 Reloads entire extension | 🟡 Reloads entire extension |
| Respects Content Script `run_at` | ✅ | ✅ | ❌ ESM-style loaders run asynchronously |
| <strong style="opacity: 50%">Built-in Utils</strong> | | | |
| Storage | ✅ | ✅ | ❌ |
| Messaging | ❌ | ✅ | ❌ |
| Content Script UI | ✅ | ✅ | ❌ |
## Why use WXT?
WXT's main goal is improving the development experience (DX) of creating web extensions, while not sacrificing support. There are two things WXT does differently:
1. Automatically opens a browser with the extension installed when starting development
2. Reload each part of the extension individually rather than reloading the entire extension
Opening a browser automatically makes it super easy to start and stop development without having to manually load the extension in your browser.
Reloading each part of the extension individually improves your iteration speed while developing UIs. This is because reloading the entire extension on every change will close the popup and any tabs open to an extension page, like options. If you save a file associated with a UI and a content script while working on the UI, it will randomly close because it needed to reload the extension when the content script changed. This interrupts your development flow and is really annoying.
WXT solves this problem by reloading HTML pages and content scripts individually (when possible) to keep your UIs open while you develop them. This is a MV3 feature, so if you're developing a MV2 extension, you'll get the same dev experience as Plasmo.
:::info
Unfortunately, there isn't an API for reloading the background page/service worker individually, so if you change a file used by the background, the entire extension will reload. See [Issue #53](https://github.com/wxt-dev/wxt/issues/53) for more details.
:::
@@ -1,8 +1,6 @@
# Configuration
WXT's behavior can be configured via the `wxt.config.ts` file. In this file, you can add Vite plugins, change the directory strucutre of your project, and provide permissions or other fields to the `<outdir>/manifest.json`.
However, since WXT is an opinionated framework, some things cannot be configured.
WXT's behavior can be configured via the `wxt.config.ts` file. In this file, you can add Vite plugins, change the directory structure of your project, and set fields on your `manifest.json`.
## Config File
@@ -17,7 +15,7 @@ export default defineConfig({
```
:::info
See the [API reference](/api.md) for a full list of options.
See the [Config reference](/api/wxt/interfaces/InlineConfig) for a full list of options.
:::
## Directory Config
@@ -25,13 +23,24 @@ See the [API reference](/api.md) for a full list of options.
WXT allows you to edit several directories to your liking:
- `root` (default: `process.cwd()`) - Root of the WXT project
- `srcDir` (default: `<root>`) - Location of all your source code
- `srcDir` (default: `<rootDir>`) - Location of all your source code
- `entrypointsDir` (default: `<srcDir>/entrypoints`) - Folder containing all the entrypoints.
- `publicDir` (default: `<srcDir>/public`) - Folder containing [public assets](/get-started/assets.md)
- `publicDir` (default: `<srcDir>/public`) - Folder containing [public assets](/guide/assets)
### Example
If you want a `src/` directory to contain all your source code, and you want to rename `entrypoints/` to `entries/`, your config would look like this:
You want a `src/` directory to contain all your source code, and you want to rename `entrypoints/` &rarr; `entries/`:
```
<rootDir>
├─ src/
│ └─ entries/
│ ├─ background.ts
│ └─ ...
└─ wxt.config.ts
```
Your config would look like this:
```ts
import { defineConfig } from 'wxt';
@@ -42,12 +51,6 @@ export default defineConfig({
});
```
## Vite Config
[Vite](https://vitejs.dev/) is the bundler used to build each entrypoint of your extension. Vite can be configured via the `vite` option.
See [Vite's documentation](https://vitejs.dev/config/) for configuring the bundler.
## Frontend Frameworks
Adding a framework like Vue, React, or Svelte is easy!
@@ -61,9 +64,9 @@ import { defineConfig } from 'wxt';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
vite: {
vite: () => ({
plugins: [vue()],
},
}),
});
```
@@ -72,9 +75,9 @@ import { defineConfig } from 'wxt';
import react from '@vitejs/plugin-react';
export default defineConfig({
vite: {
vite: () => ({
plugins: [react()],
},
}),
});
```
@@ -83,10 +86,14 @@ import { defineConfig } from 'wxt';
import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({
vite: {
vite: () => ({
plugins: [svelte()],
},
}),
});
```
:::
:::info
Internally, WXT runs `vite build` multiple times during a single build. It can't share the same instance of some plugins between each build, so a function is used to return completely new instances of each plugin for each build.
:::
+408
View File
@@ -0,0 +1,408 @@
# Content Script UI
There are three ways to mount a UI inside a content script:
[[toc]]
Each has their own set of advantages and disadvantages.
| Method | Isolated Styles | Isolated Events | HMR | Use page's context |
| ----------- | :-------------: | :-----------------: | :-: | :----------------: |
| Integrated | ❌ | ❌ | ❌ | ✅ |
| Shadow Root | ✅ | ✅ (off by default) | ❌ | ✅ |
| IFrame | ✅ | ✅ | ✅ | ❌ |
## Integrated
Integrated content script UIs are injected alongside the content of a page. This means that they are affected by CSS on that page.
:::code-group
```ts [Vanilla]
// entrypoints/example-ui.content.ts
export default defineContentScript({
matches: ['<all_urls>'],
main(ctx) {
const ui = createIntegratedUi(ctx, {
position: 'inline',
onMount: (container) => {
// Append children to the container
const app = document.createElement('p');
app.textContent = '...';
container.append(app);
},
});
// Call mount to add the UI to the DOM
ui.mount();
},
});
```
```ts [Vue]
// entrypoints/example-ui.content/index.ts
import { createApp } from 'vue';
import App from './App.vue';
export default defineContentScript({
matches: ['<all_urls>'],
main(ctx) {
const ui = createIntegratedUi(ctx, {
position: 'inline',
onMount: (container) => {
// Create the app and mount it to the UI container
const app = createApp(App);
app.mount(container);
return app;
},
onRemove: (app) => {
// Unmount the app when the UI is removed
app.unmount();
},
});
// Call mount to add the UI to the DOM
ui.mount();
},
});
```
```tsx [React]
// entrypoints/example-ui.content/index.tsx
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
export default defineContentScript({
matches: ['<all_urls>'],
main(ctx) {
const ui = createIntegratedUi(ctx, {
position: 'inline',
onMount: (container) => {
// Create a root on the UI container and render a component
const root = ReactDOM.createRoot(container);
root.render(<App />);
return root;
},
onRemove: (root) => {
// Unmount the root when the UI is removed
root.unmount();
},
});
// Call mount to add the UI to the DOM
ui.mount();
},
});
```
```ts [Svelte]
// entrypoints/example-ui.content/index.ts
import App from './App.svelte';
export default defineContentScript({
matches: ['<all_urls>'],
main(ctx) {
const ui = createIntegratedUi(ctx, {
position: 'inline',
onMount: (container) => {
// Create the Svelte app inside the UI container
const app = new App({
target: container,
});
return app;
},
onRemove: (app) => {
// Destroy the app when the UI is removed
app.$destroy();
},
});
// Call mount to add the UI to the DOM
ui.mount();
},
});
```
```tsx [Solid]
// entrypoints/example-ui.content/index.ts
import { render } from 'solid-js/web';
export default defineContentScript({
matches: ['<all_urls>'],
main(ctx) {
const ui = createIntegratedUi(ctx, {
position: 'inline',
onMount: (container) => {
// Render your app to the UI container
const unmount = render(() => <div>...</div>, container);
},
onRemove: (unmount) => {
// Unmount the app when the UI is removed
unmount();
},
});
// Call mount to add the UI to the DOM
ui.mount();
},
});
```
:::
See the [API Reference](/api/wxt/client/functions/createIntegratedUi) for the complete list of options.
You can control how CSS is injected for an integrated content script UI with the [`cssInjectionMode`](/api/wxt/interfaces/BaseContentScriptEntrypointOptions#cssinjectionmode) property. Usually, you'll want to leave it as `"manifest"`, the default, so the UI inherits its style from the website's CSS.
## Shadow Root
Often in web extensions, you don't want your content script's CSS affecting the page, or vise-versa. The [`ShadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot) API is ideal for this.
WXT's [`createShadowRootUi`](/api/wxt/client/functions/createShadowRootUi) abstracts all the `ShadowRoot` setup away, making it easy to create UIs with isolated CSS. It also supports an optional `isolateEvents` parameter to further isolate user interactions.
To use `createShadowRootUi`, follow these steps:
1. Import your CSS file at the top of your content script
2. Set [`cssInjectionMode: "ui"`](/api/wxt/interfaces/BaseContentScriptEntrypointOptions#cssinjectionmode) inside `defineContentScript`
3. Define your UI with `createShadowRootUi()`
4. Mount the UI so it is visible to users
:::code-group
```ts [Vanilla]
// 1. Import the style
import './style.css';
export default defineContentScript({
matches: ['<all_urls>'],
// 2. Set cssInjectionMode
cssInjectionMode: 'ui',
async main(ctx) {
// 3. Define your UI
const ui = await createShadowRootUi(ctx, {
name: 'example-ui',
position: 'inline',
onMount(container) {
// Define how your UI will be mounted inside the container
const app = document.createElement('p');
app.textContent = 'Hello world!';
container.append(app);
},
});
// 4. Mount the UI
ui.mount();
},
});
```
```ts [Vue]
// 1. Import the style
import './style.css';
import { createApp } from 'vue';
import App from './App.vue';
export default defineContentScript({
matches: ['<all_urls>'],
// 2. Set cssInjectionMode
cssInjectionMode: 'ui',
async main(ctx) {
// 3. Define your UI
const ui = await createShadowRootUi(ctx, {
name: 'example-ui',
position: 'inline',
onMount: (container) => {
// Define how your UI will be mounted inside the container
const app = createApp(App);
app.mount(container);
return app;
},
onRemove: (app) => {
// Unmount the app when the UI is removed
app?.unmount();
},
});
// 4. Mount the UI
ui.mount();
},
});
```
```tsx [React]
// 1. Import the style
import './style.css';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
export default defineContentScript({
matches: ['<all_urls>'],
// 2. Set cssInjectionMode
cssInjectionMode: 'ui',
async main(ctx) {
// 3. Define your UI
const ui = await createShadowRootUi(ctx, {
name: 'example-ui',
position: 'inline',
onMount: (container) => {
// Container is a body, and React warns when creating a root on the body, so create a wrapper div
const app = document.createElement('div');
container.append(app);
// Create a root on the UI container and render a component
const root = ReactDOM.createRoot(app);
root.render(<App />);
return root;
},
onRemove: (root) => {
// Unmount the root when the UI is removed
root?.unmount();
},
});
// 4. Mount the UI
ui.mount();
},
});
```
```ts [Svelte]
// 1. Import the style
import './style.css';
import App from './App.svelte';
export default defineContentScript({
matches: ['<all_urls>'],
// 2. Set cssInjectionMode
cssInjectionMode: 'ui',
async main(ctx) {
// 3. Define your UI
const ui = await createShadowRootUi(ctx, {
name: 'example-ui',
position: 'inline',
onMount: (container) => {
// Create the Svelte app inside the UI container
const app = new App({
target: container,
});
return app;
},
onRemove: (app) => {
// Destroy the app when the UI is removed
app?.$destroy();
},
});
// 4. Mount the UI
ui.mount();
},
});
```
```tsx [Solid]
// 1. Import the style
import './style.css';
import { render } from 'solid-js/web';
export default defineContentScript({
matches: ['<all_urls>'],
// 2. Set cssInjectionMode
cssInjectionMode: 'ui',
async main(ctx) {
// 3. Define your UI
const ui = await createShadowRootUi(ctx, {
name: 'example-ui',
position: 'inline',
onMount: (container) => {
// Render your app to the UI container
const unmount = render(() => <div>...</div>, container);
},
onRemove: (unmount) => {
// Unmount the app when the UI is removed
unmount?.();
},
});
// 4. Mount the UI
ui.mount();
},
});
```
:::
See the [API Reference](/api/wxt/client/functions/createShadowRootUi) for the complete list of options.
:::info TailwindCSS
`createShadowRootUi` supports TailwindCSS out of the box! When importing the styles, just import the main CSS file containing the `@tailwind` directives, and everything will just work :+1:.
:::
## IFrame
If you don't need to run your UI in the same frame as the content script, you can use an IFrame to host your UI instead. Since an IFrame just hosts an HTML page, **_HMR is supported_**.
WXT provides a helper function, [`createIframeUi`](/api/wxt/client/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>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Your Content Script IFrame</title>
</head>
<body>
<!-- ... -->
</body>
</html>
```
1. Add the page to the manifest's `web_accessible_resources`
```ts
// wxt.config.ts
export default defineConfig({
manifest: {
web_accessible_resources: [
{
resources: ['example-iframe.html'],
matches: [...],
},
],
},
});
```
1. Create and mount the IFrame
```ts
export default defineContentScript({
matches: ['<all_urls>'],
main(ctx) {
// Define the UI
const ui = createIframeUi(ctx, {
page: '/example-iframe.html',
position: 'inline',
onMount: (wrapper, iframe) => {
// Add styles to the iframe like width
iframe.width = '123';
},
});
// Show UI to user
ui.mount();
},
});
```
See the [API Reference](/api/wxt/client/functions/createIframeUi) for the complete list of options.
-62
View File
@@ -1,62 +0,0 @@
# Content Scripts
[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/content_scripts/) &bull; [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts)
## Filenames
When a filename matches the pattern below, it is added as a content script in the `manifest.json`.
- `entrypoints/content.tsx?`
- `entrypoints/<name>.content.tsx?`
- `entrypoints/content/index.tsx?`
- `entrypoints/<name>.content/index.tsx?`
## Definition
```ts
export default defineContentScript({
// Set manifest options
matches: ['*://google.com/*', '*://duckduckgo.com/*'],
excludeMatches: undefined | [],
includeGlobs: undefined | [],
excludeGlobs: undefined | [],
allFrames: undefined | [],
runAt: undefined | 'document_start' | 'document_end' | 'document_idle',
matchAboutBlank: undefined | true | false,
matchOriginAsFallback: undefined | true | false,
world: undefined | 'ISOLATED' | 'MAIN',
main() {
// Executed when content script is loaded
},
});
```
> All manifest options default to `undefined`.
When defining multiple content scripts, content script entrypoints that have the same set of options will be merged into a single `content_script` item in the manifest.
## CSS
To include CSS with your content script, import the CSS file at the top of your entrypoint:
```
<srcDir>
└─ entrypoints/
└─ overlay.content/
├─ index.ts
└─ style.css
```
```ts
// entrypoints/overlay.content/index.ts
import './style.css';
export default defineContentScript({
matches: ['*://google.com/*', '*://duckduckgo.com/*'],
main() {
// ...
},
});
```
+116
View File
@@ -0,0 +1,116 @@
# Development
WXT's main goal is providing the best DX it possibly can. When running your extension in dev mode, each part of your extension is reloaded separately when possible.
| | HMR | Reloaded individually | Reload extension | Restart browser |
| ------------------- | :-: | :-------------------: | :--------------: | :----------------------------------------------------: |
| HTML File | | ✅ |
| HTML Dependency | ✅ |
| MV3 Content Script | | ✅ |
| MV2 Content Script | | | ✅ |
| Background | | | ✅ |
| manifest.json | | | | 🟡 See [#16](https://github.com/wxt-dev/wxt/issues/16) |
| `wxt.config.ts` | | | | 🟡 See [#10](https://github.com/wxt-dev/wxt/issues/10) |
| `web-ext.config.ts` | | | | 🟡 See [#10](https://github.com/wxt-dev/wxt/issues/10) |
## Dev Mode vs Production Builds
There are some notable differences between the development and production versions of an extension. During development:
1. **Content scripts are not listed in the `manifest.json`** when targeting MV3. Instead, the [`scripting`](https://developer.chrome.com/docs/extensions/reference/api/scripting) permission is used to register content scripts at runtime so they can be reloaded individually.
To get the list of content scripts during development, run the following in the background's console:
```ts
await chrome.scripting.getRegisteredContentScripts();
```
2. **The CSP is modified to allow loading scripts from the dev server**. Make sure you're using Chrome v110 or above for HMR to work.
3. If you don't include a background script/service worker, one will be created to perform various tasks in dev mode, mostly related to reloading different parts of the extension on change.
For production builds, none of the above modifications will be applied, and you're extension/manifest will only include what you have defined.
## Configure Browser Startup
WXT uses [`web-ext` by Mozilla](https://github.com/mozilla/web-ext) to automatically open a browser with the extension installed. You can configure the runner's behavior via the [`runner`](/api/wxt/interfaces/InlineConfig#runner) option, or in a separate gitignored file, `web-ext.config.ts`.
:::code-group
```ts [wxt.config.ts]
import { defineConfig } from 'wxt';
export default defineConfig({
runner: {
// Runner config
},
});
```
```ts [web-ext.config.ts]
import { defineRunnerConfig } from 'wxt';
export default defineRunnerConfig({
// Runner config
});
```
:::
### Browser Binaries
`web-ext`'s browser discovery is very limited. By default, it only guesses at where Chrome and Firefox are installed. If you've customized your install locations, you may need to tell `web-ext` where the binaries/executables are located using the [`binaries` option](/api/wxt/interfaces/ExtensionRunnerConfig#binaries). For other Chromium based browsers, like Edge or Opera, you'll need to explicitly list them in the `binaries` option as well, otherwise they will open in Chrome by default.
```ts
// ~/web-ext.config.ts
import { defineRunnerConfig } from 'wxt';
export default defineRunnerConfig({
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"
},
});
```
:::tip
When configuring browser binaries, it's helpful to put them in `~/web-ext.config.ts` instead of the project directory's `web-ext.config.ts` file. When placed in your home directory (`~/`), this config will be used by all WXT projects, so you only need to configure the binaries once.
:::
### Other options
You can customize other options as well, like startup URLs, profiles, or additional command line arguments:
```ts
// web-ext.config.ts
import { defineRunnerConfig } from 'wxt';
export default defineRunnerConfig({
startUrls: ['https://google.com', 'https://duckduckgo.com'],
chromiumProfile: '/path/to/profile/to/use',
chromiumArgs: ['--window-size=400,300'],
});
```
For a full list of options, see the [API Reference](/api/wxt/interfaces/ExtensionRunnerConfig).
## Reload the Extension
Normally, to manually reload an extension, you have to visit `chrome://extensions` and click the reload button for your extension.
When running `wxt` command to start the dev server, WXT adds a keyboard shortcut `Alt+R`, that reloads the extension when pressed, without visiting `chrome://extensions`. This can also be customized or disabled:
```ts [wxt.config.ts]
import { defineConfig } from 'wxt';
export default defineConfig({
dev: {
reloadCommand: 'Alt+T', // false, to disable
},
});
```
:::info
This shortcut is only available during development, and is not be added to your extension when running `wxt build` or `wxt-zip`.
:::
-26
View File
@@ -1,26 +0,0 @@
# Devtools
[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/devtools/) &bull; [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/devtools_page)
## Filenames
- `entrypoints/devtools.html`
- `entrypoints/devtools/index.html`
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<!-- ... -->
</body>
</html>
```
+141
View File
@@ -0,0 +1,141 @@
# Defining Entrypoints
An "entrypoint" is any HTML, JS, or CSS file that needs to be bundled and included with the extension.
Entrypoints may or may not be listed in the extension's `manifest.json`.
## `/entrypoints` Directory
In WXT, entrypoints are defined by adding a file to the `entrypoints/` directory.
For example, a project that looks like this:
```
<rootDir>
└─ entrypoints/
├─ background.ts
├─ content.ts
├─ injected.ts
└─ popup.html
```
would result in the following `manifest.json`:
```json
{
// ...
"manifest_version": 3,
"action": {
// ...
"default_popup": "popup.html"
},
"background": {
// ...
"service_worker": "background.js"
},
"content_scripts": [
{
// ...
"js": ["content-scripts/content.js"]
}
]
}
```
If a file uses a special name recognized by WXT, it will be added to the manifest. In this case:
- `popup.html` &rarr; `action.default_popup`
- `content.ts` &rarr; `content_scripts.0.js.0`
- `background.ts` &rarr; `background.service_worker`
But not all entrypoints are added to the `manifest.json`. If the filename is not recognized by WXT, they are still built and included in the extension, but they are considered "unlisted" and are not apart of the manifest.
In this case, `injected.ts` gets output to `<outdir>/injected.js` and is accessible via `browser.runtime.getURL("/injected.js")`.
:::info
See [`/entrypoints` folder](/entrypoints/background) documentation for a full list of recognized entrypoint filenames.
:::
## Entrypoint Options
Some entrypoints, like content scripts, actions, or the background, can receive additional options.
In HTML files, options are listed as `meta` tags:
```html
<html>
<head>
<!-- Defining the popup's "default_icon" field -->
<meta name="manifest.default_icon" content="{ '16': '/icon/16.png' }" />
</head>
</html>
```
In TS files, options are apart of the file's default export:
```ts
export default defineContentScript({
matches: ['*://*.google.com/*'],
runAt: 'document_start',
main() {
// ...
},
});
```
:::info
For a full list of entrypoints and each of their options, see the [`/entrypoints` folder](/entrypoints/background) documentation.
:::
### Side Effects
You cannot use imported variables outside the `main` function in JS entrypoints. This includes options, as shown below:
```ts
// entrypoints/content.ts
import { GOOGLE_MATCHES } from '~/utils/match-patterns';
export default defineContentScript({
matches: GOOGLE_MATCHES,
main() {
// ...
},
});
```
```
$ wxt build
wxt build
WXT 0.14.1
Building chrome-mv3 for production with Vite 5.0.5
✖ Command failed after 360 ms
[8:55:54 AM] ERROR entrypoints/content.ts: Cannot use imported variable "GOOGLE_MATCHES" before main function. See https://wxt.dev/guide/entrypoints.html#side-effects
```
This throws an error because WXT needs to import each entrypoint during the build process to extract its definition (containing the `match`, `runAt`, `include`/`exclude`, etc.) to render the `manifest.json` correctly. Before loading an entrypoint, a transformation is applied to remove all imports. This prevents imported modules (local or NPM) with side-effects from running during the build process, potentially throwing an error.
:::details Why?
When importing your entrypoint to get its definition, the file is imported in a **_node environment_**, and doesn't have access to the `window`, `chrome`, or `browser` globals a web extension usually has access to. If WXT doesn't remove all the imports from the file, the imported modules could try and access one of these variables, throwing an error.
:::
:::warning
See [`wxt-dev/wxt#336`](https://github.com/wxt-dev/wxt/issues/336) to track the status of this bug.
:::
Usually, this error occurs when you try to extract options into a shared file or try to run code outside the `main` function. To fix the example from above, use literal values when defining an entrypoint instead of importing them:
```ts
import { GOOGLE_MATCHES } from '~/utils/match-patterns'; // [!code --]
export default defineContentScript({
matches: GOOGLE_MATCHES, // [!code --]
matches: ['*//*.google.com/*'], // [!code ++]
main() {
// ...
},
});
```
+38
View File
@@ -0,0 +1,38 @@
# ES Modules
Configure entrypoints to use ESM at runtime.
Currently, ESM entrypoints are opt-in, so you must configure each entrypoint with that in mind.
## HTML Pages <Badge type="warning" text="≥0.0.1" />
In general, you should always make HTML pages import ESM scripts, unless you need to support old browsers.
To make a script ESM, add `type="module"`:
<!-- prettier-ignore -->
```html
<script src="./main.ts"></script> <!-- [!code --] -->
<script src="./main.ts" type="module"></script> <!-- [!code ++] -->
```
## Background <Badge type="warning" text="≥0.16.0" />
In your background script, set `type: "module"`:
```ts
export default defineBackground({
type: 'module', // !code ++
main() {
// ...
},
});
```
:::warning
Only MV3 support ESM background scripts/service workers. When targeting MV2, the `type` option is ignored and the background is always bundled into a single file as IIFE.
:::
## Content Scripts
Coming soon. Follow [Content Script ESM Support #357](https://github.com/wxt-dev/wxt/issues/357) for updates.
+22 -22
View File
@@ -11,12 +11,14 @@ And that's it! Your extension now supports Chrome, Firefox, Safari, Edge, and ot
## Basic Usage
The `browser` variable is available globally via [auto-imports](/guide/auto-imports.md), or it can be imported manually.
The `browser` variable is available globally via [auto-imports](/guide/auto-imports), or it can be imported manually.
```ts
import browser from 'webextension-polyfill';
import { browser } from 'wxt/browser';
```
The `wxt/browser` module exports a customized version of `webextension-polyfill`'s browser with improved typing.
### Example
Let's save the date the extension was installed. Just like `chrome`, some APIs require the permission is added to your manifest before the API is defined. Here, we need to add the `storage` permission to your manifest.
@@ -37,9 +39,9 @@ Then we can use `browser.storage` to save the install date to local storage.
```ts
// background.ts
export default defineBackground(() => {
browser.runtime.onInstall.addEventListener(({ reason }) => {
browser.runtime.onInstalled.addListener(({ reason }) => {
if (reason === 'install') {
browser.storage.local.setItem({ installDate: Date.now() });
browser.storage.local.set({ installDate: Date.now() });
}
});
});
@@ -51,34 +53,32 @@ Follow [Chrome's message passing guide](https://developer.chrome.com/docs/extens
Here's a basic request/response example:
```ts
// background.ts
export default defineBackground(() => {
browser.runtime.onMessage.addEventListener(
(message, sender, sendResponse) => {
console.log(message); // "ping"
// Wait 1 second and respond with "pong"
setTimeout(() => sendResponse('pong'), 1000);
return true;
},
);
});
```
```ts
// popup/main.ts
const res = await browser.runtime.sendMessage('ping');
console.log('res'); // "pong"
console.log(res); // "pong"
```
```ts
// background.ts
export default defineBackground(() => {
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message); // "ping"
// Wait 1 second and respond with "pong"
setTimeout(() => sendResponse('pong'), 1000);
return true;
});
});
```
There are a number of message passing libraries you can use to improve the message passing experience.
Here are some that are compatible with WXT (because they are based off `webextension-polyfill` as well):
- [`@webext-core/messaging`](https://webext-core.aklinker1.io/guide/proxy-service/) - "A light-weight, type-safe wrapper around the `browser.runtime` messaging APIs"
- [`@webext-core/proxy-service`](https://webext-core.aklinker1.io/guide/messaging/) - "Create TRPC-like services that can be called from anywhere but run in the background"
- [`@webext-core/messaging`](https://webext-core.aklinker1.io/guide/messaging/) - "A light-weight, type-safe wrapper around the `browser.runtime` messaging APIs"
- [`@webext-core/proxy-service`](https://webext-core.aklinker1.io/guide/proxy-service/) - "Create TRPC-like services that can be called from anywhere but run in the background"
- [`webext-bridge`](https://github.com/zikaari/webext-bridge) - "Messaging in Web Extensions made super easy. Out of the box."
## Browser Differences
+116
View File
@@ -0,0 +1,116 @@
# Handling Extension Updates
When releasing an update to your extension, there's a couple of things you need to keep in mind:
[[toc]]
## Content Script Cleanup
Old content scripts are not automatically stopped when an extension updates and reloads. Often, this leads to "Invalidated context" errors in production when a content script from an old version of your extension tries to use a web extension API (ie, the `browser` or `chrome` globals).
WXT provides a utility for handling this process: `ContentScriptContext`. An instance of this class is provided to you automatically inside the `main` function of each content script.
When your extension updates or reloads, the context will become invalidated, and will trigger any `ctx.onInvalidated` listeners you add:
```ts
export default defineContentScript({
main(ctx) {
ctx.onInvalidated(() => {
// Do something
});
},
)
```
The `ctx` also provides other convenient APIs for stopping your content script without manually calling `onInvalidated` to add a listener:
1. Setting timers:
```ts
ctx.setTimeout(() => { ... }, ...);
ctx.setInterval(() => { ... }, ...);
ctx.requestAnimationFrame(() => { ... });
```
1. Adding DOM events:
```ts
ctx.addEventListener(window, "mousemove", (event) => { ... });
```
1. Implements [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) for canceling standard APIs:
```ts
fetch('...', {
signal: ctx.signal,
});
```
Other WXT APIs require a `ctx` object so they can clean themselves up. For example, [`createIntegratedUi`](/guide/content-script-ui#integrated), [`createShadowRootUi`](/guide/content-script-ui#shadow-root), and [`createIframeUi`](/guide/content-script-ui#iframe) automatically unmount and stop a UI when the script is invalidated.
:::warning
When working with content scripts, **you should always use the `ctx` object to stop any async or future work.**
This prevents old content scripts from interfering with new content scripts, and prevents error messages from being logged to the console in production.
:::
## Testing Permission Changes
When `permissions`/`host_permissions` change during an update, depending on what exactly changed, Chrome will disable your extension until the user accepts the new permissions.
It is possible to test this before you release an update, but it's not a simple process:
1. Get 2 ZIPs of your extension, both generated by `wxt zip`. The first contains a previous version of your extension, the second contains the latest version. Make sure the second ZIP's version is higher than the first's.
2. Unzip the two ZIP files somewhere next to each other that's easy to locate.
3. In Chrome, open `chrome://extensions` and make sure developer mode is enabled
4. Pack the first extension into a CRX, generating a new private key:
1. Click "Pack Extension" in the top left
2. For "Extension root directory", enter the path to the first extracted zip directory. The directory should contain a `manifest.json` file
3. Leave "Private key file" blank
4. Click "Pack Extension". This will generate a `.crx` and `.pem` file
5. Pack the second extension into a CRX, reusing the private key generated by the previous step
1. Click "Pack Extension" in the top left
2. For "Extension root directory", enter the path to the second extracted zip directory.
3. For "Private key file", enter the path to the generated `.pem` private key file
4. Click "Pack Extension". This will generate a second `.crx` file.
6. Install the first CRX file by dragging and dropping it onto the `chrome://extensions` page
7. Install the second CRX file by dragging and dropping it onthe the `chrome://extensions` page
If a new permission must be accepted, you'll be prompted to accept it after dropping the second CRX file onto the page.
:::Info Note
Note: Chrome no longer allows self-signed CRX extensions to run, but that's OK for this test case. We're still prompted to accept new permissions, even if we can't interact with the installed extension.
To validate this, you can create a third ZIP file with a rare permission like `geolocation` in the manifest, that's guarenteed to reprompt permissions when added.
:::
## Update Event
You can setup a callback that runs after your extension updates like so:
```ts
browser.runtime.onInstalled.addListener(({ reason }) => {
if (reason === 'update') {
// Do something
}
});
```
If the logic is simple, write a unit test to cover this logic. If you feel the need to manually test this callback, you can either:
1. In dev mode, remove the `if` statement and reload the extension from `chrome://extensions`
2. Build two ZIPs with the same runtime ID and actually update the extension
The first approach is very straightforward. The second is more complicated...
Here are the steps:
So the steps:
1. Checkout an old commit.
2. [Add a `key`](https://developer.chrome.com/docs/extensions/reference/manifest/key#keep-consistent-id) to the `manifest` in your `wxt.config.ts`.
3. Run `wxt zip` to create the first ZIP.
4. Stash or reset changes and checkout your latest code.
5. Add back the same `key` to your manifest.
6. Make sure the extension's version is higher than the first zip. It can be any version that's higher, since you won't be releasing this version.
7. Run `wxt zip` to create the second ZIP.
8. In a fresh chrome profile, go to `chrome://extensions`, enable dev mode, and drag and drop the first zip onto the page to install it.
9. In the extension, play around and setup your test case.
10. Back on `chrome://extensions`, drag and drop your second zip onto the page.
If you setup the `key` correctly, it will cause the extension to act like it was updated instead of installing a second version of your extension.
+164
View File
@@ -0,0 +1,164 @@
# Installation
Bootstrap a new project, start from scratch, or [migrate an existing project](/guide/migrate-to-wxt).
## Bootstrap Project
:::code-group
```sh [pnpm]
pnpm dlx wxt@latest init <project-name>
```
```sh [npm]
npx wxt@latest init <project-name>
```
```sh [bun]
bunx wxt@latest init <project-name>
```
:::
There are several starting templates available.
| TypeScript |
| ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <Icon name="TypeScript" /> [`vanilla`](https://github.com/wxt-dev/wxt/tree/main/templates/vanilla) |
| <Icon name="Vue" /> [`vue`](https://github.com/wxt-dev/wxt/tree/main/templates/vue) |
| <Icon name="React" /> [`react`](https://github.com/wxt-dev/wxt/tree/main/templates/react) |
| <Icon name="Svelte" /> [`svelte`](https://github.com/wxt-dev/wxt/tree/main/templates/svelte) |
| <Icon name="Solid" icon="https://www.solidjs.com/img/favicons/favicon-32x32.png" /> [`solid`](https://github.com/wxt-dev/wxt/tree/main/templates/solid) |
:::info
All templates default to TypeScript. Rename the file extensions to `.js` to use JavaScript instead.
:::
## From Scratch
Create a new NPM project:
:::code-group
```sh [pnpm]
mkdir project-name
cd project-name
pnpm init
echo 'shamefully-hoist=true' >> .npmrc
```
```sh [npm]
mkdir project-name
cd project-name
npm init
```
```sh [yarn]
mkdir project-name
cd project-name
yarn init
```
```sh [bun]
mkdir project-name
cd project-name
bun init
```
:::
Then install `wxt`:
:::code-group
```sh [pnpm]
pnpm add -D wxt
```
```sh [npm]
npm i --save-dev wxt
```
```sh [yarn]
yarn add --dev wxt
```
```sh [bun]
bun add --dev wxt
```
:::
Add your first entrypoint:
```ts
// entrypoints/background.ts
export default defineBackground(() => {
console.log(`Hello from ${browser.runtime.id}!`);
});
```
Finally, add scripts to your `package.json`:
```json
{
"scripts": {
"dev": "wxt", // [!code ++]
"dev:firefox": "wxt --browser firefox", // [!code ++]
"build": "wxt build", // [!code ++]
"build:firefox": "wxt build --browser firefox", // [!code ++]
"zip": "wxt zip", // [!code ++]
"zip:firefox": "wxt zip --browser firefox", // [!code ++]
"postinstall": "wxt prepare" // [!code ++]
}
}
```
## Migrate an Existing Project
Before starting the migration, it is recommended to run `pnpm dlx wxt@latest init` to see what a basic project looks like. Once you have an understanding of how WXT projects are structured, you're ready to convert the project, using the initialized project as a reference.
Migrating a project to WXT comes down to a few steps:
1. Install WXT and remove any old build tools: `pnpm i -D wxt`
1. Refactoring/move your entrypoints to the `entrypoints` directory
1. Moving public assets to the `public` directory
1. Update the dev and build scripts to use WXT
1. Ensure project is compatible with Vite, which is used under the hood to bundle your extension
:::info
Since projects vary greatly in setup, [start a discussion on GitHub](https://github.com/wxt-dev/wxt/discussions/new/choose) if you need help migrating your project to WXT.
:::
## Development
Once you've installed WXT, you can start the development server using the `dev` script.
```sh
pnpm dev
```
:::tip 🎉&ensp;Well done!
The dev command will build the extension for development, open the browser, and reload the different parts of the extension when you save changes.
:::
:::details Development Manifest
When running the dev command, WXT will make several changes to your `manifest.json` to improve your development experience:
- If missing, add a background script/service worker to enable fast reloads
- Add several `permissions` and `host_permissions` to enable HMR and fast reloads
- Modify the CSP to allow connections with the dev server
- Remove `content_scripts` and register them at runtime so they can be easily reloaded when you save a file
If you're an experienced web extension developer and think the dev manifest looks wrong, this is why. Run a production build with `wxt build` to see the unmodified `manifest.json`.
:::
## Next Steps
You're ready to build your web extension!
- Learn how to [add entrypoints](./entrypoints) like the popup, options page, or content scripts
- Configure your entrypoints to [use ESM](./esm) at runtime
- [Configure WXT](./configuration) by creating a `wxt.config.ts` file
- Checkout [example projects](https://github.com/wxt-dev/wxt-examples) to see how to perform common tasks with WXT
@@ -1,19 +1,26 @@
---
head:
- - link
- rel: canonical
href: https://wxt.dev
---
# Introduction
WXT is a free and open source framework for building web extensions in an conventional, intuative, and safe way **_for all browsers_**.
WXT is a free and open source framework for building web extensions in an conventional, intuitive, and safe way **_for all browsers_**.
WXT comes with full TypeScript support and auto-imports. Sounds familiar? That's right, **_WXT was based off of Nuxt_** and aims to provide the same greate DX and features.
WXT is based of [Nuxt](https://nuxt.com), and aims to provide the same great DX with TypeScript, auto-imports, and an opinionated project structure.
![Example build output](../assets/cli-output.png)
## Conventions
WXT is an optionated framework. This helps keep projects consistent and easy to pick up.
WXT is an opinionated framework. This helps keep projects consistent and easy to pick up.
- **Generated manifest**: Based on your project's file structure
- **Entrypoint configuration**: Configure entrypoints from the same file they're declare in
- **Type-safety is a priority**: Out-of-the-box TypeScript support with improved browser API typing
- **Simple output file structure**: Ouptut file paths minimize the path at runtime
- **Simple output file structure**: Output file paths minimize the path at runtime
## Development
@@ -28,5 +35,5 @@ Production builds are optimized for store review, changing as few files as possi
In addition, WXT fully supports Firefox's source code requirements when using a bundler. It will automatically create and upload a ZIP file of your source code.
:::info
See [Publishing](./publishing.md) for more info around production builds.
See [Publishing](./publishing) for more info around production builds.
:::
+139 -16
View File
@@ -1,12 +1,17 @@
---
outline: deep
---
# Manifest.json
The manifest.json is generated at build-time based on files in your `entrypoints` directory and your `wxt.config.ts`.
The manifest.json is generated at build-time based on files in the `entrypoints/` directory and `wxt.config.ts`.
## Customization
## Configuration
While entrypoints are generated and added to the manifest at build-time, you can customize or add to your `manifest.json` in the config file.
```ts
// wxt.config.ts entrypoint of your extension
import { defineConfig } from 'wxt';
export default defineConfig({
@@ -19,18 +24,20 @@ export default defineConfig({
});
```
## `name`
### `name`
If not provided via the `manifest` config, the [manifest's `name`](https://developer.chrome.com/docs/extensions/mv3/manifest/name/) defaults to your package.json's `name` property.
## `version` and `version_name`
### `version` and `version_name`
The [manifest's `version` and `version_name`](https://developer.chrome.com/docs/extensions/mv3/manifest/version/) fields are based on your package.json's `version` property.
The [manifest's `version` and `version_name`](https://developer.chrome.com/docs/extensions/mv3/manifest/version/) properties are based on the `version` field listed in your `package.json` or `wxt.config.ts`.
- `version_name` is the exact string listed in your package.json
- `version_name` is the exact string listed in your `package.json` or `wxt.config.ts` file
- `version` is the string cleaned up, with any invalid suffixes removed
### Example
If a version is not found, a warning is logged and the version defaults to `"0.0.0"`.
#### Example
```json
// package.json
@@ -49,7 +56,7 @@ The [manifest's `version` and `version_name`](https://developer.chrome.com/docs/
### `icons`
The [manifest's `icons`](https://developer.chrome.com/docs/extensions/mv3/manifest/icons/) property needs to be set in the config file. The files should be added to WXT's [`public` directory](/get-started/assets#public-directory).
By default, WXT will discover icons in your [`public` directory](/guide/assets#public-directory) and use them for the [manifest's `icons`](https://developer.chrome.com/docs/extensions/mv3/manifest/icons/).
```
public/
@@ -60,21 +67,27 @@ public/
└─ icon-128.png
```
Icon files need to match the following regex to be automatically included in the manifest. Most design software can output icons in one of these formats
<<< @/../packages/wxt/src/core/utils/manifest.ts#snippet
If you prefer to use filenames in a different format, you can add the icons manually in your `wxt.config.ts` file:
```ts
export default defineConfig({
manifest: {
icons: {
16: '/icon-16.png',
24: '/icon-24.png',
48: '/icon-48.png',
96: '/icon-96.png',
128: '/icon-128.png',
16: '/extension-icon-16.png',
24: '/extension-icon-24.png',
48: '/extension-icon-48.png',
96: '/extension-icon-96.png',
128: '/extension-icon-128.png',
},
},
});
```
### Permissions
### `permissions`
[Permissions](https://developer.chrome.com/docs/extensions/reference/permissions/) must be listed in the manifest config.
@@ -86,9 +99,9 @@ export default defineConfig({
});
```
### Localization
## Localization
Similar to the icon, the [`_locales` directory](https://developer.chrome.com/docs/extensions/reference/i18n/) should be placed inside the the WXT's [`public` directory](/get-started/assets#public-directory).
Similar to the icon, the [`_locales` directory](https://developer.chrome.com/docs/extensions/reference/i18n/) should be placed inside the the WXT's [`public` directory](/guide/assets#public-directory).
```
public/
@@ -112,3 +125,113 @@ export default defineConfig({
},
});
```
See the official localization examples for more details:
<ExampleList tag="i18n" />
## Per-Manifest Version Config
WXT applies several transformations to your manifest to simplify managing both MV2 and MV3 keys in your `wxt.config.ts` file:
1. Top level MV2-only or MV3-only keys are stripped from the final manifest when targeting the other manifest version
2. Some keys, are automatically converted between versions when possible:
- Define `web_accessible_resources` in it's MV3 style and it will be converted to the MV2 style automatically
- `action` will automatically be converted to `browser_action` for MV3. To use `page_action` instead, add both `action` and `page_action` entries to your manifest
For example, a `wxt.config.ts` file that looks like this:
```ts
import { defineConfig } from 'wxt';
export default defineConfig({
mainfest: {
action: {
default_title: 'Some Title',
},
web_accessible_resources: [
{
matches: ['*://*.google.com/*'],
resources: ['icon/*.png'],
},
],
},
});
```
Will be output differently for each manifest version:
:::code-group
```json [MV2]
{
"manifest_version": 2,
// ...
"browser_action": {
"default_title": "Some Title"
},
"web_accessible_resources": ["icon/*.png"]
}
```
```json [MV3]
{
"manifest_version": 3,
// ...
"action": {
"default_title": "Some Title"
},
"web_accessible_resources": [
{
"matches": ["*://*.google.com/*"],
"resources": ["icon/*.png"]
}
]
}
```
:::
:::tip
If this isn't enough control for your use-case, remember you can use a function for the `manifest` key and generate it however you'd like, or you can use the `build:manifestGenerated` hook to apply additional transformations.
:::
## Per-Browser Configuration
The `manifest` field can be a function. If you are building and extension for multiple browsers, and need to modify the manifest per browser, using a function instead of an object is very useful.
```ts
export default defineConfig({
manifest: ({ browser, manifestVersion, mode, command }) => {
return {
// Your manifest
};
},
});
```
:::info
The first argument is of type `ConfigEnv`. See the [API reference](/api/wxt/interfaces/ConfigEnv) for info about each property.
:::
For example, say you use OAuth, and you need to provide a different `oauth.client_id` for each browser:
```ts
const clientIds = {
chrome: '<your-chrome-client-id>',
edge: '<your-edge-client-id>',
firefox: '<your-firefox-client-id>',
opera: '<your-opera-client-id>',
};
export default defineConfig({
manifest: ({ browser }) => ({
oauth: {
client_id: clientIds[browser],
scopes: [
// ...
],
},
}),
});
```
+57
View File
@@ -0,0 +1,57 @@
---
outline: deep
---
# Migrate to WXT
> If you have problems migrating to WXT, feel free to ask for help in GitHub by [starting a discussion](https://github.com/wxt-dev/wxt/discussions/new?category=q-a)!
## Overview
Always start by generating a new vanilla project and merging it into your project one file at a time.
```sh
cd path/to/your/project
pnpm dlx wxt@latest init example-wxt --template vanilla
```
In general, you'll need to:
<input type="checkbox" /> Install `wxt`<br />
<input type="checkbox" /> Update/create `package.json` scripts to use `wxt` (don't forget about `postinstall`)<br />
<input type="checkbox" /> Move entrypoints into `entrypoints/` directory<br />
<input type="checkbox" /> Move assets into either the `assets/` or `public/` directories<br />
<input type="checkbox" /> Move manifest.json content into `wxt.config.ts`<br />
<input type="checkbox" /> Convert custom import syntax to be compatible with Vite<br />
<input type="checkbox" /> Add a default export to JS entrypoints<br />
<input type="checkbox" /> Use the `browser` global instead of `chrome`<br />
<input type="checkbox" /> Compare final `manifest.json` files, making sure permissions and host permissions are unchanged<br />
<input type="checkbox" /> Extension output by `wxt build` works the same way as before the migration<br />
Every project is different, so there's no one-solution-fits-all to migrating your project. Just make sure `wxt dev` runs, `wxt build` results in a working extension, and the list of permissions in the `manifest.json` hasn't changed. If all that looks good, you've finished migrating your extension!
## Popular Tools/Frameworks
Here's specific steps for other popular frameworks/build tools.
### `vite-plugin-web-extension`
Since you're already using Vite, it's a simple refactor.
1. Install `wxt`
2. Move and refactor your entrypoints to WXT's style (with a default export)
3. Update package.json scripts to use `wxt`
4. Add `"postinstall": "wxt prepare"` script
5. Move the `manifest.json` into `wxt.config.ts`
6. Move any custom settings from `vite.config.ts` into `wxt.config.ts`'s
7. Compare `dist/manifest.json` to `.output/*/manifest.json`, they should have the same content as before. If not, tweak your entrypoints and config to get as close as possible.
### `plasmo`
1. Install `wxt`
2. Move entrypoints into `entrypoints/` directory, merging the named exports used to configure your JS entrypoints into WXT's default export
3. Move public `assets/*` into the `public/` directory
4. If you use CSUI, migrate to WXT's `createContentScriptUi`
5. Convert Plasmo's custom import resolutions to Vite's
6. If importing remote code via a URL, add a `url:` prefix so it works with WXT
7. Compare your output `manifest.json` files from before the migration to after the migration. They should have the same content. If not, tweak your entrypoints and config to get as close as possible.
+133
View File
@@ -0,0 +1,133 @@
# Multiple Browsers
You can build an extension for any combination of browser and manifest version. Different browsers and manifest versions support different APIs and entrypoints, so be sure to check that your extension functions as expected for each target.
Separate build targets are written to their own output directories:
```
<rootDir>
└─ .output
├─ chrome-mv3
├─ firefox-mv2
├─ edge-mv3
└─ ...
```
## Target Browser
To build for a specific browser, pass the `-b --browser` flag from the CLI:
```sh
wxt --browser firefox
wxt build --browser firefox
```
By default, it will build for `chrome`. When excluding the [manifest version flags](#target-manifest-version), it will default to the commonly accepted manifest version for that browser.
| Browser | Default Manifest Version |
| ---------------- | :----------------------: |
| `chrome` | 3 |
| `firefox` | 2 |
| `safari` | 2 |
| `edge` | 3 |
| Any other string | 3 |
:::tip
To configure which browser is opened when running dev mode via `wxt -b <browser>`, see the [Development docs](/guide/development#configure-browser-startup) docs.
:::
## Target Manifest Version
To build for a specific manifest version, pass either the `--mv2` flag or `--mv3` flag from the CLI.
```sh
wxt --mv2
wxt build --mv2
```
When the `-b --browser` flag is not passed, it defaults to `chrome`. So here, we're targeting MV2 for Chrome.
## Customizing Entrypoints
There are several ways to customize entrypoint definitions per browser.
First, you can use either the `include` or `exclude` option to include or exclude the entrypoint from specific browsers. Here are some examples
:::code-group
```ts [Background]
export default defineBackground({
// Only include a background script when targeting chrome
include: ['chrome'],
});
```
```ts [Content Script]
export default defineContentScript({
// Do not add this content script to the manifest when targeting firefox
exclude: ['firefox'],
});
```
```html [HTML page]
<!-- entrypoints/options.html -->
<html>
<head>
<!-- Don't include the options page for safari -->
<meta name="manifest.exclude" content="['safari']" />
</head>
</html>
```
:::
Second, you can change individual options per-browser:
:::code-group
```ts [Background]
export default defineBackground({
persistent: {
// Use a non-persistent background script for just safari
safari: false,
},
});
```
```ts [Content Script]
export default defineContentScript({
matches: {
// Run the content script on different pages for each browser
chrome: ['*://*.google.com/*'],
firefox: ['*://*.duckduckgo.com/*'],
edge: ['*://*.bing.com/*'],
},
});
```
:::
:::warning
Only `defineBackground` and `defineContentScript` support per-browser options right now.
:::
## Runtime
To determine the browser or manifest version at runtime, you can use any of the below variables:
- `import.meta.env.BROWSER`: A string, the target browser, usually equal to the `--browser` flag
- `import.meta.env.MANIFEST_VERSION`: A number, either `2` or `3`, depending on the manifest version targeted
- `import.meta.env.CHROME`: A boolean equivalent to `import.meta.env.BROWSER === "chrome"`
- `import.meta.env.FIREFOX`: A boolean equivalent to `import.meta.env.BROWSER === "firefox"`
- `import.meta.env.EDGE`: A boolean equivalent to `import.meta.env.BROWSER === "edge"`
- `import.meta.env.SAFARI`: A boolean equivalent to `import.meta.env.BROWSER === "safari"`
- `import.meta.env.OPERA`: A boolean equivalent to `import.meta.env.BROWSER === "opera"`
- `import.meta.env.COMMAND`: A string, `"serve"` when running `wxt` for development or `"build"` in all other cases.
:::info
These variables are constants defined at build time based on the build target. They do not actually detect which browser the code is running in.
For example, if you build for `--browser chrome` and publish it on Edge, `import.meta.env.BROWSER` will be `"chrome"`, not `"edge"`. You have to build a separate ZIP for `--browser edge` before `import.meta.env.BROWSER` will be `"edge"`.
If you need to know the actual browser your code is being ran on, you should use a [user agent parser](https://www.npmjs.com/package/ua-parser-js).
:::
+238
View File
@@ -0,0 +1,238 @@
---
outline: deep
---
# Publishing
WXT will help you ZIP your extensions and submit them to the stores for review.
## First Time Publishing
If you're publishing an extension to a store for the first time, you must manually navigate the process. WXT doesn't help you create listings, each store has unique steps and requirements that you need to familiarize yourself with.
For specific details about each store, see the stores sections below.
- [Chrome Web Store](#chrome-web-store)
- [Firefox Addon Store](#firefox-addon-store)
- [Edge Addons](#edge-addons)
## Automation
WXT provides two commands to help automate the release process:
- `wxt submit`: Submit new versions of your extension for review (and publish them automatically once approved)
- `wxt submit init`: Help setup all the required secrets and options for the `wxt submit` command
To get started, run `wxt submit init` and follow the prompts. Once finished, you should have a `.env.submit` file! WXT will use this file to submit your updates.
> In CI, make sure you add all the environment variables to the submit step.
To release an update, build all the ZIPs you plan on releasing:
```sh
wxt zip
wxt zip -b firefox
```
Then run the `wxt submit` command, passing in all the ZIP files you want to release. In this case, we'll do a release for all 3 major stores: Chrome Web Store, Edge Addons, and Firefox Addons Store.
If it's your first time running the command, you'll want to test your secrets by passing the `--dry-run` flag:
```sh
wxt submit --dry-run \
--chrome-zip .output/<your-extension>-<version>-chrome.zip \
--firefox-zip .output/<your-extension>-<version>-firefox.zip --firefox-sources-zip .output/<your-extension>-<version>-sources.zip \
--edge-zip .output/<your-extension>-<version>-chrome.zip
```
If the dry run passes, remove the flag and do the actual release:
```sh
wxt submit \
--chrome-zip .output/<your-extension>-<version>-chrome.zip \
--firefox-zip .output/<your-extension>-<version>-firefox.zip --firefox-sources-zip .output/<your-extension>-<version>-sources.zip \
--edge-zip .output/<your-extension>-<version>-chrome.zip
```
:::tip
If you only need to release to a single store, only pass that store's ZIP flag.
:::
:::tip
See the [Firefox Addon Store](#firefox-addon-store) section for more details about the `--firefox-sources-zip` option.
:::
## GitHub Action
Here's an example of a GitHub Action that submits new versions of an extension for review. Ensure that you've added all required secrets used in the workflow to the repo's settings.
```yml
name: Release
on:
workflow_dispatch:
jobs:
submit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 'latest'
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Zip extensions
run: |
pnpm zip
pnpm zip:firefox
- name: Submit to stores
run: |
pnpm wxt submit \
--chrome-zip .output/*-chrome.zip \
--firefox-zip .output/*-firefox.zip --firefox-sources-zip .output/*-sources.zip
env:
CHROME_EXTENSION_ID: ${{ secrets.CHROME_EXTENSION_ID }}
CHROME_CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }}
CHROME_CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }}
CHROME_REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }}
FIREFOX_EXTENSION_ID: ${{ secrets.FIREFOX_EXTENSION_ID }}
FIREFOX_JWT_ISSUER: ${{ secrets.FIREFOX_JWT_ISSUER }}
FIREFOX_JWT_SECRET: ${{ secrets.FIREFOX_JWT_SECRET }}
```
The action above lays the foundation for a basic workflow, including `zip` and `submit` steps. To further enhance your GitHub Action and delve into more complex scenarios, consider exploring the following examples from real projects. They introduce advanced features such as version management, changelog generation, and GitHub releases, tailored for different needs:
- [`aklinker1/github-better-line-counts`](https://github.com/aklinker1/github-better-line-counts/blob/main/.github/workflows/submit.yml) - Conventional commits, automated version bump and changelog generation, triggered manually, optional dry run for testing
- [`GuiEpi/plex-skipper`](https://github.com/GuiEpi/plex-skipper/blob/main/.github/workflows/deploy.yml) - Triggered automatically when `package.json` version is changed, creates and uploads artifacts to GitHub release.
> These examples are designed to provide clear insights and are a good starting point for customizing your own workflows. Feel free to explore and adapt them to your project needs.
## Stores
### Chrome Web Store
> ✅ Supported &bull; [Developer Dashboard](https://chrome.google.com/webstore/developer/dashboard) &bull; [Publishing Docs](https://developer.chrome.com/docs/webstore/publish/)
To create a ZIP for Chrome:
```sh
wxt zip
```
### Firefox Addon Store
> ✅ Supported &bull; [Developer Dashboard](https://addons.mozilla.org/developers/) &bull; [Publishing Docs](https://extensionworkshop.com/documentation/publish/submitting-an-add-on/)
Firefox requires you to upload a ZIP of your source code. This allows them to rebuild your extension and review the code in a readable way. More details can be found in [Firefox's docs](https://extensionworkshop.com/documentation/publish/source-code-submission/).
WXT fully supports generating and automatically submitting a source code ZIP.
When you run `wxt zip -b firefox`, your sources are zipped into the `.output` directory alongside the extension. WXT will automatically exclude certain files such as config files, hidden files, and tests. However, it's important to manually check the ZIP to ensure it only contains the files necessary to rebuild your extension.
To customize which files are zipped, add the `zip` option to your config file.
```ts
// wxt.config.ts
import { defineConfig } from 'wxt';
export default defineConfig({
zip: {
// ...
},
});
```
If it's your first time submitting to the Firefox Addon Store, or if you've updated your project layout, always test your sources ZIP! The commands below should allow you to rebuild your extension from inside the extracted ZIP.
:::code-group
```sh [pnpm]
pnpm i
pnpm zip:firefox
```
```sh [npm]
npm i
npm run zip:firefox
```
```sh [yarn]
yarn
yarn zip:firefox
```
```sh [bun]
bun i
bun zip:firefox
```
:::
Make sure the build output is the exact same when running `wxt build -b firefox` in your main project and inside the zipped sources.
:::warning
If you use a `.env` files, they can effect the chunk hashes in the output directory. Either delete the .env file before running `wxt zip -b firefox`, or include it in your sources zip with the [`zip.includeSources`](/api/wxt/interfaces/InlineConfig#includesources) option. Be careful to not include any secrets in your `.env` files.
See Issue [#377](https://github.com/wxt-dev/wxt/issues/377) for more details.
:::
Ensure that you have a `README.md` or `SOURCE_CODE_REVIEW.md` file with the above commands so that the Firefox team knows how to build your extension.
#### Private Packages
If you use private packages and you don't want to provide your auth token to the Firefox team during the review process, you can use `zip.downloadPackages` to download any private packages and include them in the zip.
```ts
// wxt.config.ts
export default defineConfig({
zip: {
downloadPackages: [
'@mycompany/some-package',
//...
],
},
});
```
Depending on your package manager, the `package.json` in the sources zip will be modified to use the downloaded dependencies via the `overrides` or `resolutions` field.
:::warning
WXT uses the command `npm pack <package-name>` to download the package. That means regardless of your package manager, you need to properly setup a `.npmrc` file. NPM and PNPM both respect `.npmrc` files, but Yarn and Bun have their own ways of authorizing private registries, so you'll need to add an `.npmrc` file.
:::
### Safari
> 🚧 Not supported yet
WXT does not currently support automated publishing for Safari. Safari extensions require a native MacOS or iOS app wrapper, which WXT does not create yet. For now, if you want to publish to Safari, follow this guide:
- [Converting a web extension for Safari](https://developer.apple.com/documentation/safariservices/safari_web_extensions/converting_a_web_extension_for_safari) - "Convert your existing extension to a Safari web extension using Xcodes command-line tool."
When running the `safari-web-extension-converter` CLI tool, pass the `.output/safari-mv2` or `.output/safari-mv3` directory, not your source code directory.
```sh
pnpm wxt build -b safari
xcrun safari-web-extension-converter .output/safari-mv2
```
### Edge Addons
> ✅ Supported &bull; [Developer Dashboard](https://aka.ms/PartnerCenterLogin) &bull; [Publishing Docs](https://learn.microsoft.com/en-us/microsoft-edge/extensions-chromium/publish/publish-extension)
No need to create a specific ZIP for Edge. If you're already publishing to the Chrome Web Store, you can reuse your Chrome ZIP.
However, if you have features specifically for Edge, create a separate ZIP with:
```sh
wxt zip -b edge
```
+31
View File
@@ -0,0 +1,31 @@
# Remote Code
WXT will automatically download and bundle imports with the `url:` prefix so the extension does not depend on remote code, [a requirement from Google for MV3](https://developer.chrome.com/docs/extensions/migrating/improve-security/#remove-remote-code).
## Google Analytics
For example, you can import Google Analytics:
```ts
// utils/google-analytics.ts
import 'url:https://www.googletagmanager.com/gtag/js?id=G-XXXXXX';
window.dataLayer = window.dataLayer || [];
// NOTE: This line is different from Google's documentation
window.gtag = function () {
dataLayer.push(arguments);
};
gtag('js', new Date());
gtag('config', 'G-XXXXXX');
```
Then you can import this in your HTML files to enable Google Analytics:
```ts
// popup/main.ts
import '~/utils/google-analytics';
gtag('event', 'event_name', {
key: 'value',
});
```
-32
View File
@@ -1,32 +0,0 @@
# Sandbox
[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/manifest/sandbox/)
:::tip Chromium Only
Firefox does not support sandboxed pages.
:::
## Filenames
- `entrypoints/sandbox.html`
- `entrypoints/<name>.sandbox.html`
- `entrypoints/sandbox/index.html`
- `entrypoints/<name>.sandbox/index.html`
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<!-- ... -->
</body>
</html>
```
-32
View File
@@ -1,32 +0,0 @@
# Side Panel
[Chrome Docs](https://developer.chrome.com/docs/extensions/reference/sidePanel/)
:::tip Chromium Only
Firefox does not support sandboxed pages.
:::
## Filenames
- `entrypoints/sidepanel.html`
- `entrypoints/<name>.sidepanel.html`
- `entrypoints/sidepanel/index.html`
- `entrypoints/<name>.sidepanel/index.html`
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<!-- ... -->
</body>
</html>
```
+281
View File
@@ -0,0 +1,281 @@
---
outline: deep
---
# Storage API
WXT provides a simplified API to replace the `browser.storage.*` APIs. Use the `storage` auto-import from `wxt/storage` or import it manually to get started:
```ts
import { storage } from 'wxt/storage';
```
:::warning
To use the `wxt/storage` API, the `"storage"` permission must be added to the manifest:
```ts
// wxt.config.ts
export default defineConfig({
manifest: {
permissions: ['storage'],
},
});
```
More info on permissions [here](/guide/manifest#permissions).
:::
[[toc]]
## Basic Usage
All storage keys must be prefixed by their storage area.
```ts
// ❌ This will throw an error
await storage.getItem('installDate');
// ✅ This is good
await storage.getItem('local:installDate');
```
You can use `local:`, `session:`, `sync:`, or `managed:`.
If you use TypeScript, you can add a type parameter to most methods to specify the expected type of the key's value:
```ts
await storage.getItem<number>('local:installDate');
await storage.watch<number>(
'local:installDate',
(newInstallDate, oldInstallDate) => {
// ...
},
);
await storage.getMeta<{ v: number }>('local:installDate');
```
For a full list of methods available, see the [API reference](/api/wxt/storage/interfaces/WxtStorage).
## Watchers
To listen for storage changes, use the `storage.watch` function. It lets you setup a listener for a single key:
```ts
const unwatch = storage.watch<number>('local:counter', (newCount, oldCount) => {
console.log('Count changed:', { newCount, oldCount });
});
```
To remove the listener, call the returned `unwatch` function:
```ts
const unwatch = storage.watch(...);
// Some time later...
unwatch();
```
## Metadata
`wxt/storage` also supports setting metadata for keys, stored at `key + "$"`. Metadata is a collection of properties associated with a key. It might be a version number, last modified date, etc.
[Other than versioning](#versioning), you are responsible for managing a field's metadata:
```ts
await Promise.all([
storage.setItem('local:preference', true),
storage.setMeta('local:preference', { lastModified: Date.now() }),
]);
```
When setting different properties of metadata from multiple calls, the properties are combined instead of overwritten:
```ts
await storage.setMeta('local:preference', { lastModified: Date.now() });
await storage.setMeta('local:preference', { v: 2 });
await storage.getMeta('local:preference'); // { v: 2, lastModified: 1703690746007 }
```
You can remove all metadata associated with a key, or just specific properties:
```ts
// Remove all properties
await storage.removeMeta('local:preference');
// Remove one property
await storage.removeMeta('local:preference', 'lastModified');
// Remove multiple properties
await storage.removeMeta('local:preference', ['lastModified', 'v']);
```
## Defining Storage Items
Writing the key and type parameter for the same key over and over again can be annoying. As an alternative, you can use `storage.defineItem` to create a "storage item".
Storage items contain the same APIs as the `storage` variable, but you can configure its type, default value, and more in a single place:
```ts
// utils/storage.ts
const showChangelogOnUpdate = storage.defineItem<boolean>(
'local:showChangelogOnUpdate',
{
defaultValue: true,
},
);
```
Now, instead of using the `storage` variable, you can use the helper functions on the storage item you created:
```ts
await showChangelogOnUpdate.getValue();
await showChangelogOnUpdate.setValue(false);
await showChangelogOnUpdate.removeValue();
const unwatch = showChangelogOnUpdate.watch((newValue) => {
// ...
});
```
For a full list of properties and methods available, see the [API reference](/api/wxt/storage/interfaces/WxtStorageItem).
### Versioning
You can add versioning to storage items if you expect them to grow or change over time. When defining the first version of an item, start with version 1.
For example, consider a storage item that stores a list of websites that are ignored by an extension.
:::code-group
```ts [v1]
type IgnoredWebsiteV1 = string;
export const ignoredWebsites = storage.defineItem<IgnoredWebsiteV1[]>(
'local:ignoredWebsites',
{
defaultValue: [],
version: 1,
},
);
```
<!-- prettier-ignore -->
```ts [v2]
import { nanoid } from 'nanoid'; // [!code ++]
type IgnoredWebsiteV1 = string;
interface IgnoredWebsiteV2 { // [!code ++]
id: string; // [!code ++]
website: string; // [!code ++]
} // [!code ++]
export const ignoredWebsites = storage.defineItem<IgnoredWebsiteV1[]>( // [!code --]
export const ignoredWebsites = storage.defineItem<IgnoredWebsiteV2[]>( // [!code ++]
'local:ignoredWebsites',
{
defaultValue: [],
version: 1, // [!code --]
version: 2, // [!code ++]
migrations: { // [!code ++]
// Ran when migrating from v1 to v2 // [!code ++]
2: (websites: IgnoredWebsiteV1[]): IgnoredWebsiteV2[] => { // [!code ++]
return websites.map((website) => ({ id: nanoid(), website })); // [!code ++]
}, // [!code ++]
}, // [!code ++]
},
);
```
<!-- prettier-ignore -->
```ts [v3]
import { nanoid } from 'nanoid';
type IgnoredWebsiteV1 = string;
interface IgnoredWebsiteV2 {
id: string;
website: string;
}
interface IgnoredWebsiteV3 { // [!code ++]
id: string; // [!code ++]
website: string; // [!code ++]
enabled: boolean; // [!code ++]
} // [!code ++]
export const ignoredWebsites = storage.defineItem<IgnoredWebsiteV2[]>( // [!code --]
export const ignoredWebsites = storage.defineItem<IgnoredWebsiteV3[]>( // [!code ++]
'local:ignoredWebsites',
{
defaultValue: [],
version: 2, // [!code --]
version: 3, // [!code ++]
migrations: {
// Ran when migrating from v1 to v2
2: (websites: IgnoredWebsiteV1[]): IgnoredWebsiteV2[] => {
return websites.map((website) => ({ id: nanoid(), website }));
},
// Ran when migrating from v2 to v3 // [!code ++]
3: (websites: IgnoredWebsiteV2[]): IgnoredWebsiteV3[] => { // [!code ++]
return websites.map((website) => ({ ...website, enabled: true })); // [!code ++]
}, // [!code ++]
},
},
);
```
:::
:::info
Internally, this uses a metadata property called `v` to track the value's current version.
:::
In this case, we thought that the ignored website list might change in the future, and were able to setup a versioned storage item from the start.
Realistically, you won't know a item needs versioned until you need to change it's schema. Thankfully, it's simple to add versioning to an unversioned storage item.
When a previous version isn't found, WXT assumes the version was `1`. That means you just need to set `version: 2` and add a migration for `2`, and it will just work!
Lets look at the same ignored websites example from before, but start with an unversioned item this time:
:::code-group
```ts [Unversioned]
export const ignoredWebsites = storage.defineItem<string[]>(
'local:ignoredWebsites',
{
defaultValue: [],
},
);
```
<!-- prettier-ignore -->
```ts [v2]
import { nanoid } from 'nanoid'; // [!code ++]
// Retroactively add a type for the first version // [!code ++]
type IgnoredWebsiteV1 = string; // [!code ++]
interface IgnoredWebsiteV2 { // [!code ++]
id: string; // [!code ++]
website: string; // [!code ++]
} // [!code ++]
export const ignoredWebsites = storage.defineItem<string[]>( // [!code --]
export const ignoredWebsites = storage.defineItem<IgnoredWebsiteV2[]>( // [!code ++]
'local:ignoredWebsites',
{
defaultValue: [],
version: 2, // [!code ++]
migrations: { // [!code ++]
// Ran when migrating from v1 to v2 // [!code ++]
2: (websites: IgnoredWebsiteV1[]): IgnoredWebsiteV2[] => { // [!code ++]
return websites.map((website) => ({ id: nanoid(), website })); // [!code ++]
}, // [!code ++]
}, // [!code ++]
},
);
```
:::
### Running Migrations
As soon as `storage.defineItem` is called, WXT checks if migrations need to be ran, and if so, runs them. Calls to get or update the storage item's value or metadata (`getValue`, `setValue`, `removeValue`, `getMeta`, etc) will automatically wait for the migration process to finish before actually reading or writing values.
+25
View File
@@ -0,0 +1,25 @@
# Testing
## Official Frameworks
WXT officially supports [Vitest](https://vitest.dev/) for unit tests and either [Playwright](https://playwright.dev/) or [Puppeteer](https://pptr.dev/) for E2E tests against Chromium browsers.
For details setting up each testing framework, see the official examples:
<ExampleList tag="testing" />
### Unofficial Frameworks
Puppeteer and Playwright are the only E2E test runners that support Chrome Extensions. There are no other options at the time of writing.
There are other options for unit tests however, like [Jest](https://jestjs.io/), [Mocha](https://mochajs.org/), or [`node:test`](https://nodejs.org/api/test.html). **_WXT does not claim to support any of them_** because none of them support all of WXT's features, like TypeScript or auto-imports.
If you want to try to use a different framework for unit tests, you will need to configure the environment manually:
- **Auto-imports**: Add `unimport` to your test environment or disable them by setting `imports: false` in your `wxt.config.ts` file
- **`browser` mock**: Mock the `webextension-polyfill` module globally with `wxt/dist/virtual/mock-browser.js`
- **[Remote Code Bundling](/guide/remote-code)**: If you use it, configure your environment to handle the `url:` module prefix
- **Global Variables**: If you consume them, manually define globals provided by WXT (like `import.meta.env.BROWSER`) by adding them to the global scope before accessing them (`import.meta.env.BROWSER = "chrome"`)
- **Import paths**: If you use the `@/` or `~/` path aliases, add them to your test environment
[Here's how Vitest is configured](https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/testing/wxt-vitest-plugin.ts) for reference.
-42
View File
@@ -1,42 +0,0 @@
# Unlisted Pages
HTML pages that are built by Vite, but are not included in the manifest.
### Examples
- Onboarding
- Dashboard
- FAQ
- Help
- Changelog
## Filenames
- `entrypoints/<name>.html`
- `entrypoints/<name>/index.html`
Pages are accessible at `'/<name>.html'`:
```ts
const url = browser.runtime.getURL('/<name>.html');
console.log(url); // "chrome-extension://<id>/<name>.html"
```
## Definition
Plain old HTML file.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<!-- ... -->
</body>
</html>
```
-16
View File
@@ -1,16 +0,0 @@
# Unlisted Scripts
TypeScript files that are built, but are not included in the manifest.
## Filenames
- `entrypoints/<name>.tsx?`
- `entrypoints/<name>/index.tsx?`
## Definition
Unlike the background and content scripts, you can define this script's logic in the main scope.
```ts
// Code goes here
```
+35
View File
@@ -0,0 +1,35 @@
# Vite
Under the hood, WXT uses Vite to bundle your web extension.
## Basic Vite Configuration
All of Vite's config can be customized by setting the `vite` configuration in your `wxt.config.ts` file.
```ts
import { defineConfig } from 'wxt';
export default defineConfig({
vite: () => ({
// Same as `defineConfig({ ... })` inside vite.config.ts
}),
});
```
## Using Plugins
Plugins can be passed into the `vite` configuration in you `wxt.config.ts` file, just like any other option.
All plugins should work in WXT, but it is worth pointing out that since WXT orchestrates multiple vite builds to bundle an extension, plugins will be executed multiple times if necessary.
```ts
import { defineConfig } from 'wxt';
export default defineConfig({
vite: () => ({
plugins: [
// ...
],
}),
});
```
+66 -17
View File
@@ -1,49 +1,98 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home
titleTemplate: 'Next Generation Web Extension Framework'
title: Next-gen Web Extension Framework
hero:
name: WXT
text: Next gen framework for web extensions
tagline: Powered by Vite, inspired by Nuxt.
text: Next-gen Web Extension Framework
tagline: An open source tool that makes Chrome Extension development faster than ever before.
image:
src: /hero-logo.svg
alt: WXT
actions:
- theme: brand
text: Get Started
link: /get-started/installation
link: /guide/installation
- theme: alt
text: Learn More
link: /get-started/introduction
link: /guide/introduction
features:
- icon: 🌐
title: Supported Browsers
details: Chrome, Firefox, Edge, Safari, and any Chromium based browser.
details: WXT will build extensions for Chrome, Firefox, Edge, Safari, and any Chromium based browser.
link: /guide/multiple-browsers
linkText: Read docs
- icon: ✅
title: MV2 and MV3
details: Supports both manifest versions for each browser.
details: Build Manifest V2 or V3 extensions for any browser using the same codebase.
link: /guide/multiple-browsers#target-manifest-version
linkText: Read docs
- icon: ⚡
title: Fast Dev Mode
details: HMR for UIs and fast reload for background and content scripts.
details: Lighting fast HMR for UI development and fast reloads for content/background scripts enables faster iterations.
link: /guide/development.html
linkText: Learn more
- icon: 📂
title: File Based Entrypoints
details: Manifest is generated based on files inside the project.
details: Manifest is generated based on files in the project with inline configuration.
link: /guide/entrypoints
linkText: See project structure
- icon: 🚔
title: TypeScript
details: Scale projects with full TS support.
details: Create large projects with confidence using TS by default.
- icon: 🦾
title: Auto-imports
details: Nuxt-like auto-imports to speed up development.
- icon: ⬇️
title: Bundle Remote Code
details: Downloads and bundles remote code imported from URLs.
link: /guide/auto-imports
linkText: Read docs
- icon: 🤖
title: Automated Publishing
details: Automatically zip, upload, submit, and publish extensions.
- icon: 🎨
title: Frontend Framework Agnostic
details: Works with any front-end framework with a Vite plugin.
- icon: 🤖
title: Automated Publishing
details: 'TODO: Automatically zip, upload, and release extensions.'
link: /guide/configuration#frontend-frameworks
linkText: Add a framework
- icon: 🖍️
title: Bootstrap a New Project
details: Get started quickly with several awesome project templates.
link: /guide/installation#bootstrap-project
linkText: See templates
- icon: 📏
title: Bundle Analysis
details: 'TODO: Tools for analyizing the final extension bundle.'
details: Tools for analyzing the final extension bundle and minimizing your extension's size.
- icon: ⬇️
title: Bundle Remote Code
details: Downloads and bundles remote code imported from URLs.
link: /guide/remote-code
linkText: Read docs
---
<section class="vp-doc" style="padding: 0 48px">
<div class="container">
<h2>Put <span style="color: var(--vp-c-brand-1)">Developer Experience</span> First</h2>
<p>
WXT's simplifies the chrome extension development process by providing tools for zipping and publishing, the best-in-class dev mode, an opinionated project structure, and more. Iterate faster, develop features not build scripts, and use everything the JS ecosystem has to offer.
</p>
<div style="margin: auto; width: 100%; max-width: 900px; text-align: center">
<video src="https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94" controls></video>
<br />
<small>
And who doesn't appreciate a beautiful CLI?
</small>
</div>
</div>
</section>
<ClientOnly>
<UsingWxtSection />
</ClientOnly>
<style scoped>
.container {
margin: 0 auto;
max-width: 1152px;
}
</style>
+31
View File
@@ -0,0 +1,31 @@
# Netlify Redirects File
# https://docs.netlify.com/routing/redirects/
# Old URLs -> New URLs
/config.html /api/wxt/interfaces/InlineConfig.html
/api/config.html /api/wxt/interfaces/InlineConfig.html
/entrypoints /entrypoints/background.html
/get-started/assets.html /guide/assets.html
/get-started/build-targets.html /guide/multiple-browsers.html
/get-started/compare.html /guide/compare.html
/get-started/configuration.html /guide/configuration.html
/get-started/entrypoints.html /guide/entrypoints.html
/get-started/installation.html /guide/installation.html
/get-started/introduction.html /guide/introduction.html
/get-started/publishing.html /guide/publishing.html
/get-started/testing.html /guide/testing.html
/guide/background.html /entrypoints/background.html
/guide/bookmarks.html /entrypoints/bookmarks.html
/guide/content-scripts.html /entrypoints/content-scripts.html
/guide/css.html /entrypoints/css.html
/guide/devtools.html /entrypoints/devtools.html
/guide/history.html /entrypoints/history.html
/guide/manifest.html /entrypoints/manifest.html
/guide/newtab.html /entrypoints/newtab.html
/guide/options.html /entrypoints/options.html
/guide/popup.html /entrypoints/popup.html
/guide/sandbox.html /entrypoints/sandbox.html
/guide/sidepanel.html /entrypoints/sidepanel.html
/guide/unlisted-pages.html /entrypoints/unlisted-pages.html
/guide/unlisted-scripts.html /entrypoints/unlisted-scripts.html
/guide/build-targets.html /guide/multiple-browsers.html
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M354.435 418.141C383.217 418.141 406.55 394.808 406.55 366.026V313.91H416.026C444.808 313.91 468.141 290.578 468.141 261.795C468.141 233.013 444.808 209.68 416.026 209.68H406.55V157.565C406.55 128.783 383.217 105.45 354.435 105.45H302.32V95.9745C302.32 67.1921 278.987 43.8594 250.205 43.8594C221.422 43.8594 198.09 67.1921 198.09 95.9745V105.45H145.974C117.192 105.45 93.8594 128.783 93.8594 157.565V209.68H103.335C132.117 209.68 155.45 233.013 155.45 261.795C155.45 290.578 132.117 313.91 103.335 313.91H93.8594V418.141H198.09V408.665C198.09 379.883 221.422 356.55 250.205 356.55C278.987 356.55 302.32 379.883 302.32 408.665V418.141H354.435Z" stroke="#67D55E" stroke-width="20"/>
</svg>

After

Width:  |  Height:  |  Size: 798 B

+10
View File
@@ -0,0 +1,10 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_305_490)">
<path d="M348.608 492C384.905 492 414.329 462.576 414.329 426.279V360.557H426.279C462.576 360.557 492 331.132 492 294.835C492 258.538 462.576 229.114 426.279 229.114H414.329V163.392C414.329 127.095 384.905 97.6709 348.608 97.6709H282.886V85.7215C282.886 49.4245 253.462 20 217.165 20C180.868 20 151.443 49.4245 151.443 85.7215V97.6709H85.7215C49.4245 97.6709 20 127.095 20 163.392V229.114H31.9494C68.2464 229.114 97.6709 258.538 97.6709 294.835C97.6709 331.132 68.2464 360.557 31.9494 360.557H20V492H151.443V480.051C151.443 443.754 180.868 414.329 217.165 414.329C253.462 414.329 282.886 443.754 282.886 480.051V492H348.608Z" stroke="#67D55E" stroke-width="40"/>
</g>
<defs>
<clipPath id="clip0_305_490">
<rect width="512" height="512" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 914 B

+5
View File
@@ -0,0 +1,5 @@
User-agent: *
Disallow: /api.html
Disallow: /config.html
Sitemap: https://wxt.dev/sitemap.xml
Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

+12
View File
@@ -0,0 +1,12 @@
{
"$schema": "https://typedoc.org/schema.json",
"entryPointStrategy": "packages",
"entryPoints": ["../packages/wxt"],
"plugin": ["typedoc-plugin-markdown", "typedoc-vitepress-theme"],
"out": "./api",
"githubPages": false,
"excludePrivate": true,
"excludeProtected": true,
"excludeInternal": true,
"readme": "none"
}
-61
View File
@@ -1,61 +0,0 @@
import { describe, it, expect } from 'vitest';
import { TestProject } from '../utils';
describe('Auto Imports', () => {
it('should output types for entrypoint paths', async () => {
const project = new TestProject();
project.addFile(
'entrypoints/background.ts',
'export default defineBackground(() => {})',
);
project.addFile(
'entrypoints/overlay.content.ts',
'export default defineContentScript(() => {})',
);
project.addFile('entrypoints/popup.html', '<html></html>');
await project.build();
expect(await project.serializeFile('.wxt/types/paths.d.ts'))
.toMatchInlineSnapshot(`
".wxt/types/paths.d.ts
----------------------------------------
// Generated by wxt
import \\"wxt/browser\\";
declare module \\"wxt/browser\\" {
type PublicPath =
| \\"/background.js\\"
| \\"/content-scripts/overlay.js\\"
| \\"/popup.html\\"
export interface ProjectRuntime extends Runtime.Static {
getURL(path: PublicPath): string;
}
}
"
`);
});
it('should make some client utils auto-importable', async () => {
const project = new TestProject();
project.addFile('entrypoints/popup.html', `<html></html>`);
await project.build();
expect(await project.serializeFile('.wxt/types/imports.d.ts'))
.toMatchInlineSnapshot(`
".wxt/types/imports.d.ts
----------------------------------------
// Generated by wxt
export {}
declare global {
const browser: typeof import('wxt/browser')['browser']
const defineBackground: typeof import('wxt/client')['defineBackground']
const defineConfig: typeof import('wxt')['defineConfig']
const defineContentScript: typeof import('wxt/client')['defineContentScript']
const mountContentScriptUi: typeof import('wxt/client')['mountContentScriptUi']
}
"
`);
});
});
-209
View File
@@ -1,209 +0,0 @@
import { describe, it, expect } from 'vitest';
import { TestProject } from '../utils';
// TODO: move to unit tests to speed this up - this doesn't have to be in E2E tests
describe('Manifest Content', () => {
describe('popup', () => {
const popupContent = (type?: 'browser_action' | 'page_action') => `
<html>
<head>
${type == null ? '' : `<meta name="manifest.type" content="${type}">`}
<meta name="manifest.default_icon" content="{ '16': '/icon/16.png' }">
<title>Default Title</title>
</head>
</html>
`;
it('should include an action for mv3', async () => {
const project = new TestProject();
project.addFile('entrypoints/popup.html', popupContent());
await project.build();
const manifest = await project.getOutputManifest();
expect(manifest.action).toEqual({
default_icon: { '16': '/icon/16.png' },
default_title: 'Default Title',
default_popup: 'popup.html',
});
});
it.each([
[undefined, 'browser_action'],
['browser_action', 'browser_action'],
['page_action', 'page_action'],
] as const)(
'should include a browser_action for mv2',
async (type, expectedType) => {
const project = new TestProject();
project.addFile('entrypoints/popup.html', popupContent(type));
await project.build({ manifestVersion: 2 });
const manifest = await project.getOutputManifest(
'.output/chrome-mv2/manifest.json',
);
expect(manifest[expectedType]).toEqual({
default_icon: { '16': '/icon/16.png' },
default_title: 'Default Title',
default_popup: 'popup.html',
});
},
);
});
describe('options', () => {
const optionsContent = `
<html>
<head>
<meta name="manifest.open_in_tab" content="false">
<meta name="manifest.chrome_style" content="true">
<meta name="manifest.browser_style" content="true">
</head>
</html>
`;
it('should include a options_ui and chrome_style for chrome', async () => {
const project = new TestProject();
project.addFile('entrypoints/options.html', optionsContent);
await project.build();
const manifest = await project.getOutputManifest();
expect(manifest.options_ui).toEqual({
open_in_tab: false,
chrome_style: true,
page: 'options.html',
});
});
it('should include a options_ui and browser_style for firefox', async () => {
const project = new TestProject();
project.addFile('entrypoints/options.html', optionsContent);
await project.build({ browser: 'firefox' });
const manifest = await project.getOutputManifest(
'.output/firefox-mv2/manifest.json',
);
expect(manifest.options_ui).toEqual({
open_in_tab: false,
browser_style: true,
page: 'options.html',
});
});
});
describe('background', () => {
const backgroundContent = `
export default defineBackground({
persistent: true,
type: "module",
main: () => {},
})
`;
it('should include a background script for mv2', async () => {
const project = new TestProject();
project.addFile('entrypoints/background.ts', backgroundContent);
await project.build();
const manifest = await project.getOutputManifest();
expect(manifest.background).toEqual({
type: 'module',
service_worker: 'background.js',
});
});
it('should include a options_ui and browser_style for firefox', async () => {
const project = new TestProject();
project.addFile('entrypoints/background.ts', backgroundContent);
await project.build({ manifestVersion: 2 });
const manifest = await project.getOutputManifest(
'.output/chrome-mv2/manifest.json',
);
expect(manifest.background).toEqual({
persistent: true,
scripts: ['background.js'],
});
});
});
it('should group content scripts and styles together based on their matches and run_at', async () => {
const project = new TestProject();
project.addFile(
'entrypoints/one.content/index.ts',
`import "./style.css";
export default defineContentScript({
matches: ["*://google.com/*"],
main: () => {},
})`,
);
project.addFile('entrypoints/one.content/style.css', `body { color: red }`);
project.addFile(
'entrypoints/two.content/index.ts',
`import "./style.css";
export default defineContentScript({
matches: ["*://google.com/*"],
runAt: "document_end",
main: () => {},
})`,
);
project.addFile(
'entrypoints/two.content/style.css',
`body { color: green }`,
);
project.addFile(
'entrypoints/three.content/index.ts',
`import "./style.css";
export default defineContentScript({
matches: ["*://google.com/*"],
runAt: "document_end",
main: () => {},
})`,
);
project.addFile(
'entrypoints/three.content/style.css',
`body { color: blue }`,
);
project.addFile(
'entrypoints/four.content/index.ts',
`import "./style.css";
export default defineContentScript({
matches: ["*://duckduckgo.com/*"],
runAt: "document_end",
main: () => {},
})`,
);
project.addFile(
'entrypoints/four.content/style.css',
`body { color: yellow }`,
);
await project.build();
const manifest = await project.getOutputManifest();
expect(manifest.content_scripts).toContainEqual({
matches: ['*://duckduckgo.com/*'],
run_at: 'document_end',
css: ['assets/four.css'],
js: ['content-scripts/four.js'],
});
expect(manifest.content_scripts).toContainEqual({
matches: ['*://google.com/*'],
run_at: 'document_end',
css: ['assets/three.css', 'assets/two.css'],
js: ['content-scripts/three.js', 'content-scripts/two.js'],
});
expect(manifest.content_scripts).toContainEqual({
matches: ['*://google.com/*'],
css: ['assets/one.css'],
js: ['content-scripts/one.js'],
});
});
});

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