DEV Community

Cover image for Writing Chrome Extensions Using Svelte-Kit and Manifest v3

Writing Chrome Extensions Using Svelte-Kit and Manifest v3

Michel Canta on January 16, 2022

Svelte-Kit has been an amazing tool to create great responsive and reactive websites. But with its roots as a compiler, I wondered how I could use ...
Collapse
 
tohodo profile image
Tommy

Thanks for writing this up! I just tried to follow this tutorial using the latest version of SvelteKit (create-svelte version 2.0.0-next.115) and here was my experience...

  1. Upon running npm run build I got this error: "config.kit.target is no longer required, and should be removed"; so I removed this line and also reverted <div id="svelte"> back to <div> in app.html. After this change, the build was fine and I was able to locally install the extension.

  2. Upon clicking on the "Reveal current URL" button, the popup threw this JavaScript error: "Uncaught TypeError: Cannot read properties of null (reading 'parentNode') at script-13oyv3b}.js:4:62" -- the code in question is here:

import { start } from "/app/start-63ed0245.js";
start({
  target: document.querySelector('[data-hydrate="1r88ijv"]').parentNode,
  paths: {"base":"","assets":""},
  session: {},
  route: true,
  spa: false,
  trailing_slash: "never",
  hydrate: {
    status: 200,
    error: null,
    nodes: [
      import("/app/layout.svelte-733b8b62.js"),
        import("/app/pages/index.svelte-16d39772.js")
    ],
    url: new URL("http://sveltekit-prerender/"),
    params: {}
  }
});
Enter fullscreen mode Exit fullscreen mode

I'm not sure what's going on here, but it looks like it's not able to find an element with the data-hydrate attribute. Does anyone know what might be the problem?

Collapse
 
michmich112 profile image
Michel Canta

Fixed with v1.0.1-next.1. Thank you for commenting about this problem :)

Collapse
 
michmich112 profile image
Michel Canta

I know there were breaking changes in the new svelte version. I will check, there might be changes that need to be made to the adapter.

Collapse
 
matyanson profile image
Matyanson • Edited

Thanks, your post was helpful!
Just one thing I'd like to add. When you build the app and select the build folder in the extension manager, chrome has problem with the file naming:
"Cannot load extension with file or directory name _app. Filenames starting with "_" are reserved for use by the system."
I fixed that by changing the appDir property in the svelte.config.js:

extension_fix

Collapse
 
matyanson profile image
Matyanson

I tried using the "webextension-polyfill" library for cross browser compability.
It seems it is not compatible with the "sveltekit-adapter-chrome-extension" adapter.
The following error message is thrown while building at "Using sveltekit-adapter-chrome-extension" step:
"[Error: This script should only be loaded in a browser extension.]"

Perhaps I could hot fix it, but I'll stick with the chrome API for now.
Is this even necessary now when the manifest v3 is out?(for cross browser compability)

Collapse
 
michmich112 profile image
Michel Canta

I have not use the "webextension-polyfill" library but that would be interesting. I'll check it out!

Collapse
 
michmich112 profile image
Michel Canta

Yes! thank you for trying it out and noting this out!
I had to do this as well and forgot to add it to this tutorial, I will add it right away!

Collapse
 
matyanson profile image
Matyanson

Here is a template I made, hope it helps.
github.com/Matyanson/SvelteKit-bro...

Collapse
 
michmich112 profile image
Michel Canta

This is Awesome! Definitely much cleaner than what I was working with before! Starred💫

Collapse
 
relepega profile image
Relepega

In svelte v4, the adding of target: '#svelte' in svelte.config.js isn't necessary, as it throws an error and without it it compiles just fine. Anyway, great guide!

Collapse
 
michmich112 profile image
Michel Canta

Thank you for the find @relepega will add to the docs!

Collapse
 
kena profile image
KenA

Thanks for the article! One thing though, when I build the app there will be another manifest file inside the build>app folder that has no relation with the manifest file used by the chrome extension. That's ok, but if one tries to upload the package via the chrome developers dashboard in order to publish the app, it will not be possible and a msg complaining about the app having 2 manifest files will be thrown.

Collapse
 
michmich112 profile image
Michel Canta

Yes great catch, so, you're going to hate me, but you can just delete that manifest file. It has a use when you're creating a web app but not in the case of an extension. Could you create an issue in the adapter's repo and i'll be updating it to remove that manifest file automatically

Collapse
 
kena profile image
KenA

Thanks man, just added an issue in the adapter's repo as well.

Collapse
 
takaebato profile image
Takahiro Ebato • Edited

Thanks for the great adapter and blog post! About development flow, I'd like to know if I need to rebuild (and reload extension) to reflect the changes in the source code. If there is a more efficient way, could you tell me about it?
Thanks!

Collapse
 
michmich112 profile image
Michel Canta

Yes we need to for now, it might be possible with something like nodemon. i'll look into it :)

Collapse
 
takaebato profile image
Takahiro Ebato

Thanks! I'm looking forward to it!

Collapse
 
tohodo profile image
Tommy

@michmich112 I just noticed there's now another extensions adapter, which threw me off a bit. Would you happen to know what the key differences are? It seems both appear to support MV3 now.

Collapse
 
michmich112 profile image
Michel Canta

Thats great to hear! I haven't seen that project but i'm sure it works well!

Collapse
 
tohodo profile image
Tommy

Typo: should be cd my-extension

Collapse
 
michmich112 profile image
Michel Canta

Fixed! cheers

Collapse
 
tohodo profile image
Tommy

@michmich112 how do you handle chrome not being available inside a .svelte file? For example, I have route/options.svelte and inside this file I have on:input={handleInput} which saves some data using chrome.storage.local.set(). Right now it's not possible since you don't have access to chrome, so you'd have to put the logic inside scripts/options.ts which means now you have logic in two locations: options.svelte (inside <script>) and options.ts.

Collapse
 
michmich112 profile image
Michel Canta

yeah that is a problem since the chrome variable will be available globally in the execution environment. I add the no-check as its an IDE issue and not actually an issue when running it.

Collapse
 
tohodo profile image
Tommy • Edited

@michmich112 thanks for the reply. The error I got was not in the IDE but when I build from the console:

"ReferenceError: chrome is not defined"

Whenever I get this build error, it seems to also break the extension because when I reload the extension it throws this error as soon as I load the Options page:

Extension error

When I remove the code containing chrome from options.svelte and rebuild, the extension error on the Options page goes away. I ended up not using SvelteKit to build my extension. My original reason for trying out SvelteKit was the increase in performance and size when serving single-page apps, but I realized since extensions are loaded from your hard drive it's really not a big deal. I will still keep an eye on SvelteKit for other applications though :-).

Thread Thread
 
michmich112 profile image
Michel Canta

Thanks for the update, i haven't run into that problem yet but definitely something to keep an eye on! Thank you!

Collapse
 
aneesh_arora profile image
Aneesh Arora

how to add "no-check" when running npm run build? I tried to find a solution online but couldn't

Collapse
 
yamessays profile image
James Cameron

What's your final verdict? Is SvelteKit worth using or should people just use plain svelte or vanilla javascript?

Collapse
 
michmich112 profile image
Michel Canta

Hey @yamessays! Great question! I wrote another post about it to answer that question: dev.to/michmich112/should-you-use-...

Collapse
 
rickvian profile image
Rickvian Aldi • Edited

i got this error, its says could not detect production environment,
build folder doesn't show up,
will appreciate your help
dev-to-uploads.s3.amazonaws.com/up...

Collapse
 
michmich112 profile image
Michel Canta

Hey Rickvian!
Can show your svelte.config.js file? that would help me diagnose the issue easier.

Collapse
 
b4dmonkey profile image
Jo

how do you add content.js and background.js to the project? Is this something that needs to be configured in the adapter?

Collapse
 
b4dmonkey profile image
Jo

after playing around with this it looks like the proper place would be under the static dir

Collapse
 
czachandrew profile image
Andrew Czachowski

Don't know if I'm the only one to come across this but in the current version of svelte.config.js make sure in kit to add prerender: {default: true} if you aren't seeing the generate index.html

Collapse
 
proziam profile image
Eric Biggs

As of a few days ago this will fail due to a breaking adapter change. Issue is here, github.com/michmich112/sveltekit-a...