I'm engineer who mainly uses JS/TS.
๐ญ About Me
Chrome Extension Boilerplate with React + Vite + Typescript
License: MIT License
I'm engineer who mainly uses JS/TS.
๐ญ About Me
hello,
I can't seem to get the styles to work in the content script... Haven't really done much outside the boilerplate
the pages/content/style.scss
@import "@assets/style/theme.scss";
.content-view {
font-size: 30px;
}
.clip-button {
background: black;
border-radius: 5px;
width: 30px;
height: 10px;
position: absolute;
z-index: 99;
}
the app: pages/content/components/Demo/app.tsx
import "../../style.scss";
...
return (
<div
className="clip-button"
style={{
top: pos.y,
left: pos.x,
}}
/>
);
I had originally tried to have a separate style sheet within the Demo directory itself but that also didn't work- I saw a couple of issues here saying that there was a bit of manual work involved with the config to get extra style sheets to show up so I tried using the given style sheet and it still didn't work. I'd like to get the default given style sheet working before trying something more custom. I'm new to Vite but the examples online seems to just suggest you can import the sheet as you would normally.
I feel like something like this should be pretty straightforward but have been stuck on it for a few hours and can't really find anything related on the stackoverflow so I'm not sure where to start. Any help would be appreaciated!
I don't get any errors or anything... the styles just don't show up when I inspect in the browser
Hey,
I cloned the repo and deleted the yarn.lock file as I was facing issues while installing node_modules.
after that as per the steps I run the yarn dev
command.
this created a dist
folder but the manifest.json was missing.
and because of that, I was getting this error while installing the extension
then I ran the yarn build
command which created a manifest.json file successfully
Note: but on subsequent refresh, it creates the manifest.json
I have a question, why does the content script not work with any event listeners when using the
/**
* @description
* Chrome extensions don't support modules in content scripts.
*/
import("./components/Demo");
I have to comment out the code above for the block for the rest of the code below to work, how can I render a React element in the content script while also having these document event listeners working?
console.log("content loaded");
// /**
// * @description
// * Chrome extensions don't support modules in content scripts.
// */
// import("./components/Demo");
console.log("THIS IS THE CONTENT SCRIPT GUYS");
function activityDetected(event) {
if (event.type === "mousemove") {
console.log("mouse has moved");
} else if (event.type === "blur") {
console.log("window has blurred");
} else if (event.type === "visibilitychange") {
console.log("visibility has changed");
} else if (event.type === "keydown") {
console.log("key was pressed");
}
if (!userIsActive) {
userIsActive = true;
// Send a message to the background script
chrome.runtime.sendMessage({ type: "userActive" });
}
// this got moved over to the service worker too
// resetInactivityTimeout();
}
// Add event listeners for user interactions
document.addEventListener("mousemove", activityDetected);
document.addEventListener("keydown", activityDetected);
document.addEventListener("visibilitychange", activityDetected);
window.addEventListener("blur", activityDetected);
document.addEventListener("mouseup", function () {
const selectedText = window.getSelection().toString().trim();
if (selectedText) {
console.log("Selected text:", selectedText);
// You can add your custom logic or call a function here
}
});
let userIsActive = false;
Steps to reproduce:
yarn
or yarn i
yarn dev
Issue:
Build failed with the following error at the bottom of this console output.
yarn dev
yarn run v1.22.11
$ npm run build:hmr && (run-p wss build:watch)
npm WARN lifecycle The node binary used for scripts is /var/folders/t8/m7d61j4n0dd_vnmxhsq54jkw0000gn/T/yarn--1673178526850-0.09484755126173594/node but npm is using /opt/homebrew/Cellar/node@14/14.19.3/bin/node itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed with.
> [email protected] build:hmr /Users/hussainfazaal/Experiments/phantasm
> rollup --config utils/reload/rollup.config.ts
utils/reload/initReloadServer.ts โ utils/reload/initReloadServer.js...
created utils/reload/initReloadServer.js in 1.6s
utils/reload/injections/script.ts โ utils/reload/injections/script.js...
created utils/reload/injections/script.js in 7ms
utils/reload/injections/view.ts โ utils/reload/injections/view.js...
created utils/reload/injections/view.js in 6ms
$ node utils/reload/initReloadServer.js
$ __DEV__=true vite build --watch
[HRS] Server listening at ws://localhost:8081
vite v3.1.3 building for production...
watching for file changes...
build started...
transforming (22) src/pages/newtab/Newtab.tsx Manifest file copy complete: /Users/hussainfazaal/Experiments/phantasm/dist/manifest.json
โ 23 modules transformed.
[vite:asset] Could not load /Users/hussainfazaal/Experiments/phantasm/src/assets/img/logo.svg (imported by src/pages/popup/Popup.tsx): dir.split(...).at is not a function
transforming (50) src/pages/panel/index.css
Can anyone help me resolve this issue?
thanks
your probably install vite globaly so you have no error !.
But for local instal your should change nodedemon configu like this.
{
"watch": [
"src",
"utils",
"vite.config.ts"
],
"ext": "tsx,css,html,ts",
"ignore": [
"src/**/*.spec.ts"
],
"exec": "node_modules/.bin/vite build"
}
Hello. First of all, thank you for the great boilerplate. I am getting the error message "Uncaught SyntaxError: Cannot use import statement outside a module". It is related to importing other necessary files. How can I fix it? I tried moving the imported files to resources or inside pages. But it didn't seem to be nice fix and didn't work to avoid this error. I'm wondering why this is happening because it looks like the code is in ES6?
P.S It happens in both development and processing.
When I try to run yarn dev
and open the extension all I see in the log is "background loaded" and nothing from the content script, like "content loaded". Is it correct to expect "content loaded" to be logged and what could be the reason for it not to show? Thank you!
in dev mode, the vite not as fast as expectedใinstall crx also use full static resources, so vite must build every timeใ
have any better case to make speed faster?
env:
node: v16.19.0
vite: 3.1.3
It will output success when I add this code in the makeManifest
method:
setTimeout(() => {
fs.writeFileSync(
manifestPath,
ManifestParser.convertManifestToString(manifest)
);
}, 3000)
Hello, thanks for the great boilerplate.
Everything works seamlessly, but I see 2 errors in the console. Looks like trying to load assets/js/index.js
& assets/js/jsx-runtime.js
from web page itself instead from extension.
Screenshot of github.com/...
's console.
Refused to load the script 'https://github.com/assets/js/index.js' because it violates the following Content Security Policy directive: "script-src github.githubassets.com". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
Refused to load the script 'https://github.com/assets/js/jsx-runtime.js' because it violates the following Content Security Policy directive: "script-src github.githubassets.com". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
Thank you for your help.
Hi! I've discovered this template just now. Been testing it and I love it so far! It's sooooo helpful.
I have a noobie question tho, what's the point of the new tab feature? I want to build an extension but I don't want the extension itself to replace the content of the new tab when a users installs it. Is there a way to disable this?
Hello!
Thanks for taking the time to create this boilerplate.
I'm trying to set it up but running into an odd error when clicking the Load unpacked button within chrome://extensions/
I select the dist folder then I get an modal popup error saying:
Failed to load extension
File
~/Desktop/chan-extension/dist
Error
Could not load css 'assets/css/contentStyle1679273105255.chunk.css' for content script.
Could not load manifest.
I've attached a screenshot... I can't find much info on this error online but it seems to be related incorrect naming within the manifest file?
Hi, any idea what this is complaining about?
> yarn dev
yarn run v1.22.15
$ yarn build:hmr && (yarn wss & nodemon)
$ rollup --config utils/reload/rollup.config.ts
utils/reload/initReloadServer.ts โ utils/reload/initReloadServer.js...
created utils/reload/initReloadServer.js in 2.4s
lib/reload/initReloadClient.ts โ lib/reload/initReloadClient.js...
[!] Error: Could not resolve entry module (lib/reload/initReloadClient.ts).
Error: Could not resolve entry module (lib/reload/initReloadClient.ts).
at error (/home/michal/dev/quantloupe-vite/node_modules/rollup/dist/shared/rollup.js:198:30)
at ModuleLoader.loadEntryModule (/home/michal/dev/quantloupe-vite/node_modules/rollup/dist/shared/rollup.js:22306:20)
at async Promise.all (index 0)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
I am unable to run this in dev mode. How is the dev mode done exactly and what does it do? There is no dist directory after npm run dev. Am I suppose to npm run build first? But it does not rebuild whenever I change the code. Sorry just starting out building chrome extensions
Edit: I tried the https://github.com/extend-chrome/ts-react-boilerplate.git and it works. It builds to dist and hrm also works.
I can not get the CSS modules to work. Here is what I have:
App.module.css:
.test {
color: red;
}
Inside App.tsx
I have:
import classes from "./App.module.css";
...
<h1 className={classes.test}>Some text</h1>
In the debugger, I see the transformed className, but the color is still not applied.
<h1 class="_test_11jwl_1">TEST TEXT</h1>
How can I configure CSS modules?
Hey, I'm having one issue with background scripts (screen)
I want to check if SPA url is changed, to push message to my content scripts, because I'm getting data from storage on website, but after clicking other page and coming back, this data is no longer replaced
I'm adding many different listeners to background scripts, but it seems that noone of them is working, so I assume it's connected to problem from screenshot
Any idea how I could fix that issue?
Hi,
I am trying to create a chrome notification from the background script, but it does not work. As far as I know, the iconUrl needs to be on the same directory where the manifest is, but still I get the same error. Unable to download all specified images
and not to mention that the notification is never triggered.
So this is the code:
chrome.notifications.create(
{
title: "Notification example",
iconUrl: "./LogoBg.png",
message: "Here is the message body",
type: "basic",
silent: false
},
(notificationId) => {
console.log(`notification pushed ${notificationId}`);
}
);
I have the notification permission enabled on the manifest as well.
I want to make an extension using this boilerplate I have to set up tailwindcss in this project for better dx, anyone can help me with this ?
utils/reload/initReloadServer.ts
uses chokidar.watch()
to watch for changes in dist
.
The problem is that during npm run build:watch
, the first thing that happens is that all the pre-existing files are unlinked, causing unlink
, unlinkDir
and change
events from chokidar.watch()
. Then the build process runs and eventually the new files are created causing add
and addDir
events.
But if the build takes more the 200ms the unlink events cause debounce()
to expire causing ws.send()
to send an update the the client (before the new files have been created). The client calls window.location.reload()
and we get:
Your file couldnโt be accessed
It may have been moved, edited, or deleted.
ERR_FILE_NOT_FOUND
I am attempting to use chrome api in the components but I get error
For example, while using chrome.bookmarks.create
I get this error:
TypeError: Cannot read properties of undefined (reading 'create')
I have tried globally importing chrome api by adding /*global chrome*/
to the top of the component but its not working
Hey Guys,
Thanks for a truly awesome template! I've been playing with it since Yesterday.. ๐
Just a minor suggestion - adding the sourcemap: true
to the vite.config.build when developing is a must so worth a mention in the readme IMO.
Sorry I am new to this.
I have a few functions inside content/index.ts and exporting them gives me an error. I want to call these functions inside my react components (lets say inside pages/popup/Popup.tsx)
I think I seem to generally not understand what the purpose of the content-view is because isn't it just supposed to be script? Where is the view actually rendered?
Hi I moved my project from webpackger based boilerplate to this one using Vite.
I'm also not using Typescript so not sure if this i related, but the compile takes about 8 seconds in dev mode.
It seems to be going over a 1000 files including node modules (although maybe its just checking them).
The project itself has total of 300 js files.
Any ideas what I could try to speed things up?
In contrast, vitest is extremely fast (but possibly due to the dummy test having less dependencies).
My findings so far:
According to this page: https://vitejs.dev/guide/dep-pre-bundling.html
Vite should be caching built files in node_modules/.vite
but no such directory is created in my folder.
So far I see that the build is using a production build that has no caching.
I don't mind too much as long as I can work on most of the part of the extension with the normal vite
command, but I can't yet.
I had to create an index.html
in the root of the project in order to get the dev server to serve up something, which is useful for quick development.
Hi, thanks for the great work! I'm not interested in Typescript, can I load it up with only Javascript?
์๋ ํ์ธ์. ํ์ฌ Vue ํ๋ก์ ํธ ํ์ผ์ React๋ก ๋ฆฌํฉํฐ๋ง ํ๋ ์ค ์ ๋๋ค..
๊ธฐ์กด์ Vue ํ๋ก์ ํธ์์ Background์์ ์ฌ์ฉ ๋๋ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉ ํ๋ ค๊ณ ๋ถ์ฌ ๋ฃ์์ต๋๋ค.
vite๋ก bundling์ ์ ์์ ์ผ๋ก ํ๋ ๊ฒ ๊ฐ์๋ฐ Chrome Extension์์ ์๊พธ ์ฝ์ง ๋ชปํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฒ๋ค๋ง๋ ํจํค์ง๋ชจ๋์ ํฌ๋กฌ์ต์คํ ์ ์์ importํ ๋ฐฉ๋ฒ์ด ์์๊น์?
Any recommendations on how to add tailwinds to this repo?
There's a new extension ID that gets created on new builds that prevents from me validating oauth
just wondering if you ever considered making this generally compatible with web extension to be used in firefox as well. Seems like most people use https://github.com/mozilla/webextension-polyfill
I don't understand how this works and I would appreciate it if you could help me.
I want the window to be in the middle of the page and have a specific width and height. How should I achieve this?
A common case when building an extension is that from content_script, we inject some JS code to get some infor, send back to content_script.
Detail: from content_script, we inject a file named custom_script.js
(or .ts) to the host page
But with this project setup, I don't know how to preserve custom_script.js
during compilation. Because from what I see, it's not in the dist
output folder
Could you show an example of how to get styles working with content rendered in contentView
? I've tried importing scss/css files in the react typescript files but they don't seem to be getting loaded. I also tried to mimic your runtime bundling by manually inserting a link
tag to the public contentStyle.css
file generated, but that did't work either
I inject a modal compoent into pages by content script.After build package and load extension.The image address is link to tabpage's URL instead of extension resources.How to import images in common according to content scrit
import { useState } from 'react'
import logo from '@assets/img/logo.png'
function App() {
const [modalShow, setModalShow] = useState(false)
const [modalShowAlways, setModalShowAlways] = useState(false)
const onMouseOver = () => {
if (modalShow) return
setModalShow(true)
}
const onMouseLeave = () => {
if (!modalShow) return
setModalShow(false)
}
return (
<div className="tl-helper-chrome-extension-frame">
<div className="tip">
<img src={logo} />
</div>
<div className={`tl-container ${(modalShowAlways || modalShow) ? 'modalShow' : ''}`} onMouseOver={onMouseOver} onMouseLeave={onMouseLeave}>
<div className="w100 fl fc">
<div className="tl-header fl fr">
<img className="tl-header-logo f1" src={logo} />
<div className="tl-header-title f1">xx hepler</div>
<div className="tl-header-close" onClick={() => setModalShowAlways(false)}>ร</div>
</div>
</div>
</div>
</div>
)
}
export default App
when i open it,i find it links to tabpage's url like "https://xxxx.com/assets/png/imgLogo.chunk.png" but not "chrome-extension://bhlhnicpbhignbdhedgjhgdocnmhomnp/html/assets/png/imgLogo.chunk.png"
Hi there,
Just started playing with this boilerplate and tried to update to vite 4. Looks like there are some configuration changes that break.
For some reason, even when using npm run dev
, the terminal says "vite v3.1.3 building for production...".
Makes it hard to debug since the error messages are not reported properly.
According to my research, sourcemap: true
in vite config should do the trick, but doesn't.
Any ideas?
Is it possible to have multiple CSS modules for content script ?
On this issue, the solution is to add them manually to the manifest but I'm looking a way to make it dynamic. Is it possible ?
Thanks for the help
Hi, thanks for the good template.
I was working on this template and found out that
I need to reload the extension file on chrome://extension to see the updated .scss file
can you improve on this?
thank you
Wondering the reason behind you injecting the contentView
script in the content
index.ts
rather than just directly rendering everything in the content
script? Running into a small issue where I have to manually pass the chrome extension ID in order to run any of the chrome scripts which is just a bit annoying
vite is gr8 at bundling which is very useful in tests too.
I was expecting the boilerplate to be have vitest for testing. Too bad. Can you replace jest with vitest?
I have create an extension with this boilerplate.
I want to run it on file:// scheme, while viewing pdf files.
Although the dynamic import in content script is not working.
Any ideas?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.