Skip to content

ahmed-dinar/chrome-extension-react-vite-tailwind-boilerplate

Repository files navigation

🚀 Chrome Extension Starter

Vite + React + TypeScript + Tailwind CSS + Shadcn/ui

A full-featured, ready-to-use Chrome extension template built with modern technologies - which just works!

Build Status License

preview.mp4

Table of Contents

Library and Components

  • Vite
  • 🔒 TypeScript
  • ⚛️ React
  • 🖌️ Tailwind CSS
  • 🌸 shadcn/ui
  • 📦 CRX
  • 🎭 Playwright

Development

  • 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 and options.
  • $ 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.
  • $ yarn build:watch
    
    • Runs the production build with watch mode.
    • Auto reload doesn't work in this mode, needs to manually refresh extension.

Folder and File Descriptions

  • 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 for popup, content and options.
    • 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 hooks
      • useMessage.tsx: A wrapper of chrome.runtime.onMessage usable in all popup, content and options page.
      • useSettings.tsx: Global general settings provider holds theme etc. Its sync with chrome.storage and notify all popup, content and options 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.

Auto-reload and HRM

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 or yarn build:watch, make sure to refresh the chrome extension once.

Content Scripts: CSS

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

  • 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 inside src/assets/fonts/.
    • Put font files (woff/woff2/ttf) and .css file which has @font-face.
    • Update the font-family in src/entryPoints/main.css.

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.

Add New Page

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
  • 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") });.

Setup Your Brand

Going Minimal

You may want to remove dependencies and clean up demo codes to get started from scratch.

  • Remove src/hooks and src/components/ui folders.
  • Remove src/lib/types.ts and src/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" from public/manifest.json.
  • To remove content script, delete "content_scripts" from public/manifest.json.
  • To remove popup page, delete "default_popup" from public/manifest.json.

Contributing

This is an open-source template. Contributions are welcome! Feel free to open pull requests or raise issues to help improve this project.