- Intro
- Features
- Structure
- Installation
- Install dependency
- Environment variables
- Troubleshooting
- Community
- Debugging
- Reference
ZFocus is a Chrome/Firefox extension that helps you manage your time and block distracting websites. Built with React, TypeScript, Vite, and Turborepo for optimal performance and development experience.
- React
- TypeScript
- Tailwindcss
- Vite with Rollup
- Turborepo
- Prettier
- ESLint
- Chrome Extensions Manifest Version 3
- Custom i18n package
- Custom HMR (Hot Module Rebuild) plugin
- End-to-end testing with WebdriverIO
- Clone this repository
- Ensure your node version is >= than in
.nvmrcfile, recommend to use nvm - Install pnpm globally:
npm install -g pnpm - Run
pnpm install - Check if you have that configuration in your IDE/Editor:
- VS Code:
- Installed ESLint extension
- Installed Prettier extension
- Enabled
Typescript Workbench versionin settings:- CTRL + SHIFT + P -> Search:
Typescript: Select Typescript version...->Use Workbench version - Read more
- CTRL + SHIFT + P -> Search:
- Optional, for imports to work correctly in WSL, you might need to install the Remote - WSL extension and connect to WSL remotely from VS Code. See overview section in the extension page for more information.
- WebStorm:
- VS Code:
- Run
pnpm update-version <version>for change theversionto the desired version of your extension.
Important
On Windows, make sure you have WSL enabled and Linux distribution (e.g. Ubuntu) installed on WSL.
Then, depending on the target browser:
- Run:
- Dev:
pnpm dev(on Windows, you should run as administrator; see issue#456) - Prod:
pnpm build
- Dev:
- Open in browser -
chrome://extensions - Check - Developer mode
- Click - Load unpacked in the upper left corner
- Select the
distdirectory from the boilerplate project
- Run:
- Dev:
pnpm dev:firefox - Prod:
pnpm build:firefox
- Dev:
- Open in browser -
about:debugging#/runtime/this-firefox - Click - Load Temporary Add-on... in the upper right corner
- Select the
./dist/manifest.jsonfile from the boilerplate project
Note
In Firefox, you load add-ons in temporary mode. That means they'll disappear after each browser close. You have to load the add-on on every browser launch.
- Run
pnpm i <package> -w
- Run
pnpm i <package> -F <module name>
package - Name of the package you want to install e.g. nodemon
module-name - You can find it inside each package.json under the key name, e.g. @extension/content-script, you
can use only content-script without @extension/ prefix
Read: Env Documentation
The extension lives in the chrome-extension directory and includes the following files:
manifest.ts- script that outputs themanifest.jsonsrc/background- background script (background.service_workerin manifest.json)public- icons referenced in the manifest; content CSS for user's page injection
Important
To facilitate development, the boilerplate is configured to "Read and change all your data on all websites".
In production, it's best practice to limit the premissions to only the strictly necessary websites. See
Declaring permissions
and edit manifest.js accordingly.
Code that is transpiled to be part of the extension lives in the pages directory.
content- Scripts injected into specified pages (You can see it in console)content-ui- React Components injected into specified pages (You can see it at the very bottom of pages)content-runtime- injected content scripts This can be injected from e.g.popuplike standardcontentnew-tab- override the default New Tab page (chrome_url_overrides.newtabin manifest.json)options- options page (options_pagein manifest.json)popup- popup shown when clicking the extension in the toolbar (action.default_popupin manifest.json)side-panel- sidepanel (Chrome 114+) (side_panel.default_pathin manifest.json)
Some shared packages:
dev-utils- utilities for Chrome extension development (manifest-parser, logger)env- exports object which contain all environment variables from.envand dynamically declaredhmr- custom HMR plugin for Vite, injection script for reload/refresh, HMR dev-serveri18n- custom internationalization package; provides i18n function with type safety and other validationshared- shared code for the entire project (types, constants, custom hooks, components etc.)storage- helpers for easier integration with storage, e.g. local/session storagestailwind-config- shared Tailwind config for entire projecttsconfig- shared tsconfig for the entire projectui- function to merge your Tailwind config with the global one; you can save components herevite-config- shared Vite config for the entire project
Other useful packages:
zipper- runpnpm zipto pack thedistfolder intoextension-YYYYMMDD-HHmmss.zipinside the newly createddist-zipmodule-manager- runpnpm module-managerto enable/disable modulese2e- runpnpm e2efor end-to-end tests of your zipped extension on different browsers
If saving source files doesn't cause the extension HMR code to trigger a reload of the browser page, try this:
- Ctrl+C the development server and restart it (
pnpm run dev) - If you get a
grpcerror, kill theturboprocess and runpnpm devagain.
If you are using WSL and imports are not resolving correctly, ensure that you have connected VS Code to WSL remotely using the Remote - WSL extension.