A full-featured, ready-to-use Chrome extension template built with modern technologies - which just works!
preview.mp4
- Library and Components
- Development
- Folder and File Descriptions
- Auto-reload and HRM
- Content Scripts: CSS
- Custom Fonts
- Add New Page
- Setup Your Brand
- Going Minimal
- Contributing
- ⚡ Vite
- 🔒 TypeScript
- ⚛️ React
- 🖌️ Tailwind CSS
- 🌸 shadcn/ui
- 📦 CRX
- 🎭 Playwright
- Clone the repository and
cd
to it. - Tested in node version
>=20.18.0
. So make sure its updated. -
$ yarn install
- Install dependencies
-
$ yarn dev
- Runs vite in development mood HMR enabled
- Default port is
5173
. - For popup
http://localhost:5173/popup.htm
- For options
http://localhost:5173/options.html
- For content script, open any web page.
- Auto reload works for all
popup
,content
andoptions
.
-
$ yarn build
- Just builds the extension in production mode.
-
$ yarn build:test
- Runs
lint
,prettier
and the production build. - After build runs the e2e tests.
- Runs
-
$ yarn build:watch
- Runs the production build with watch mode.
- Auto reload doesn't work in this mode, needs to manually refresh extension.
public/
: Contains all static files that are served as-is, like icons etc.manifest.json
: The manifest file that configures the extension’s permissions, background scripts, and other settings. CRXJS Vite Plugin
scripts/
: Utility script files.src/
: Contains all the source code for the extension.assets/
: Holds assets like fonts, images which compiled with vite.components/
: Holds user interface components. All the UI designs forpopup
,content
andoptions
.entryPoints/
: Main entry points of chrome extension.background.tsx
: The extension's background script.content.tsx
: The extension's content script.main.css
: Base common css contains tailwind and other global css shared with all parts of extension.options.tsx
: The extension's options page.popup.tsx
: The extension's popup page.
hooks/
: React hooksuseMessage.tsx
: A wrapper ofchrome.runtime.onMessage
usable in allpopup
,content
andoptions
page.useSettings.tsx
: Global general settings provider holds theme etc. Its sync withchrome.storage
and notify allpopup
,content
andoptions
page.
lib/
: Contains types, interface, shad cn utils etc.
tests/
: Contains all unit and e2e tests.components.json
: Generated by shadcn/ui.options.html
: The extension's options page entry file.popup.html
: The extension's popup page entry file.
With vite
and CRX Vite plugin the hot reload works out of the box. The content script also works, except for custom font files can't make it work yet.
Vite generates font-face's url without chrome extension absolute path. For build mode, implemented a workaround.
After running
yarn dev
oryarn build:watch
, make sure to refresh the chrome extension once.
For content scripts Shadow DOM is used to ensure encapsulated styles preventing interference with the content page.
Content script CSS is injected using adoptedStyleSheets when supported or via a <style>
tag as a fallback for older browser versions.
- Custom fonts can be used by placing the font files and a @font-face css inside
src/assets/fonts/
.- For example, create new folder
Roboto
insidesrc/assets/fonts/
. - Put font files (woff/woff2/ttf) and
.css
file which has@font-face
. - Update the
font-family
insrc/entryPoints/main.css
.
- For example, create new folder
The font is ready to use. workaround script will find the css file, resolve the url using chrome.runtime.getURL
.
Font files are copied by vite-plugin-static-copy
plugin.
You can add new page in chrome extension which will be available at chrome-extension://{chromeExtensionId}/[page].html
.
For example you may want to have a welcome page which opens after installing the chrome extension.
- Create a ui component in
src/components/welcome/index.tsx
- Create a entry file in
src/entryPoints/welcome.tsx
const element = document.getElementById('welcome-root')!; renderRoot(element, <WelcomeComponent />);
- Create a
welcome.html
file in root folder.- Make sure to add a id div
<div id="welcome-root"></div>
and a script tag<script type="module" src="src/entryPoints/welcome.tsx"></script>
in body
- Make sure to add a id div
- Setup entry point for vite in
vite.config.ts
"build": { "rollupOptions": { welcome: 'welcome.html' } }
Now you can access it in chrome-extension://{chromeExtensionId}/welcom.html
. Or you can open it from background script chrome.tabs.create({ url: chrome.runtime.getURL("welcome.html") });
.
- Change
ROOT_CONTAINER_ID
in/src/lib/constants.ts
- Change
sidebarTagName
in/src/entryPoints/content.tsx
- Change
prefix
intailwind.config.ts
- Change necessary infos like
name
,short_name
etc. in/public/manifest.json
- Change logo in
/src/assets/images
- Change icons in
/public
- Delete or update test codes in
/tests
You may want to remove dependencies and clean up demo codes to get started from scratch.
- Remove
src/hooks
andsrc/components/ui
folders. - Remove
src/lib/types.ts
andsrc/lib/utils.ts
files. - Clean up code inside following files. These are root file of these pages.
src/components/content/index.tsx
src/components/options/index.tsx
src/components/popup/index.tsx
src/entryPoints/background.tsx
shadcn/ui
: Remove all@radix-ui/*
,cmdk
,tailwind-merge
dependencies- Delete test codes in
/tests
Now you are ready to go from scratch!
You can also build chrome extension without content/popup/options page.
- To remove options page, delete
"options_ui"
and"options_page"
frompublic/manifest.json
. - To remove content script, delete
"content_scripts"
frompublic/manifest.json
. - To remove popup page, delete
"default_popup"
frompublic/manifest.json
.
This is an open-source template. Contributions are welcome! Feel free to open pull requests or raise issues to help improve this project.