Migration of 4 Chrome extensions from Manifest v2 to v3 (film, 33 minutes)
Welcome back to the Rusty Zone channel. In today’s video, the author discusses migrating four extensions from Manifest version 2 to version 3. The required changes are quite simple, with the main focus on changing the manifest version and updating the pop-up to use action instead of browser action. Rusty Zone also points out a few things to watch for while migrating extensions. Creating extensions can be fun and rewarding, which is why the author also mentions the availability of a new course that combines all this information in a more organized manner to help beginners build their own extensions.
The first extension being migrated is the "Word of the Day" extension. The author demonstrates the entire process of changing the manifest files, concentrating on moving the background page to a service worker, which is one of the key steps. A challenge arises when scripts and resources need adjustments, but the overall process turned out to be rather straightforward. After making the necessary changes, the author tests the extension and confirms it works as expected under Manifest version 3.
The next extension to be transformed is "Epic Mode," which plays music in the background. The author emphasizes that this time, a new file serving as an off-screen document will need to be created since background pages cannot be used. Rusty Zone explains how to add the appropriate permissions and implement the fitting code in the service worker file to facilitate the music playback. After completing these steps, the author conducts tests to ensure everything is functioning as it should.
Following that, Rusty Zone transitions the "To Do List" extension. In this case, the changes also include switching to cloud storage using Chrome Storage instead of Local Storage, which is more suitable and functional. The author provides detailed explanations with each modification, aiming to help viewers understand how to update their code and ensure the proper functioning of an extension that reliably stores data.
In conclusion, Rusty Zone summarizes the entire process of migrating the extensions and offers recommendations for those who may want to implement more complicated changes in their projects. At the video's end, Rusty Zone mentions that as of the time of writing, the video has 4544 views and 63 likes. This growing interest may encourage viewers to start migrating their own extensions to the new manifest version, given the changes brought by Manifest V3. The author encourages viewers to ask questions and share their migration experiences, highlighting collaboration within the community of extension developers.
Toggle timeline summary
-
Introduction to the channel and topic of migrating extensions.
-
Overview of the migration process from Manifest version 2 to 3.
-
Link to a previous video on building extensions.
-
Discussion about the straightforward nature of the migration.
-
Mention of a new pre-order course containing useful information.
-
Introduction to the first extension, Word of the Day.
-
Changing the manifest version to 3 and updating the background script.
-
Changing background HTML page to a service worker script.
-
Successful update of the Word of the Day extension.
-
Introduction to the second extension, Epic Mode.
-
Discussion on using an off-screen document for audio playback.
-
Changing browser action to action in the manifest.
-
Creating an off-screen document and setting up the service worker.
-
Testing the Epic Mode extension and addressing errors.
-
Introduction to the third extension, Todo List.
-
Recommendations to switch from local storage to Chrome storage.
-
Adding storage permission to the manifest.
-
Confirmation of successful updates to the Todo List extension.
-
Introduction to the fourth extension, Web Scraper.
-
Testing the Web Scraper extension and observing functionality.
-
Summary of changes needed for migrating to Manifest version 3.
-
Closing remarks and invitation for questions regarding migration.
Transcription
Hello and welcome back to the channel. Now in this video we're going to be migrating four extensions from Manifest version 2 to Manifest version 3 based on the video I've made before. I'll put a link to that in the description if you want to take a look about how to actually build these extensions. But most of these are quite straightforward so the main things would be around changing the Manifest version and updating the pop-up to be using action rather than browser action. But this goes into a little bit more detail around a few things that you want to look out for when migrating your extensions. Also a quick mention of my my new course which is still available for pre-order which is basically all of this information throughout all of my videos put together in a more organized and sort of concise way to make it easier to follow so you can build extensions and a lot of things around that as well. There's more information on that in the description if you want to pre-order. Anyway let's jump into the video now starting with the the first extension. So let's take a look at the first one here which is the Word of the Day extension. So I have all of the starting files here. Here's the Word of the Day and if we have a look at this we can see, well first we don't need this file, we have this script here, the tab, a manifest file and then we have the main sort of content here. So what we're going to do is start by going to the manifest and actually going through the changes we need to make. So the first thing that we'll see straight away is we have a background page which we can't use and we have our manifest version. So let's start by changing the manifest version to version 3. We're going to change background to a service worker. This to actually be a script rather than a like an HTML page. So we're going to change this here. So this needs to be service worker, this background and then we're going to change this to, rather than background.html, because that could be confusing, we'll just put service worker.js. So we're going to make a new file for that. The other thing we can look at as well is when we're going about migrating this, we can take a look, let's just adjust that a little bit, we can adjust our file to do this. So you can see all our HTML was doing here was just importing this JavaScript file anyway so that shouldn't be an issue for us. So we're just going to go ahead and rename this file to that new file we had. We can go ahead and delete this like that. So if we look here we can see we've updated this, we've updated this. So on the face of it our manifest file should be fine. What we need to do next is go into new service worker and just see what methods we're using to see if this is going to be okay. So if we look in we can see we have this function, that's fine. We're using a message listener which should again should be fine and that's it. So this is quite a simple extension you can see here so it's not doing too many things so that's okay. That actually reminds me one thing we're doing here with that API call is we're still waiting for this, this obviously isn't the actual API key, but we have this placeholder content here which you're just replacing and remove that. So this now looks like it should be fine. Let's just check the new tab. So that's just here and then we have this message we're going to do that. So let's go ahead and run this now and see if we get any errors. So here is our extension we've added in, let's just give it a refresh. So if we open a new tab we can see it says this page has changed, that's fine we're going to keep it. So if we refresh our page we can see that's working and it's using manifest version 3. So that was quite a simple change for this one. So that's good we've updated that. I'll share all the the completed code for this in the description as well. So that's this one done. So the next one is epic mode pop-out and background page. So this is an extension that will play music in the background. Is that right? Yeah so this is similar to the video I made, the previous video I made around we're going to need to use an off-screen document to actually pass a message through to our service worker to create a off-screen document and then play the audio there because we can't use a background page. So if we go into this one now, so this one here epic mode, and let's take a look at the manifest. So first we're going to change manifest version 2 to 3 and then we're going to take a look at this one. So here the other change we need to make is we're using browser action for the pop-out. That's just changed now to be action. So again not a massive change. So if we save this and also we're going to change this now to be a service worker. We're going to remove this and then we need to do a similar thing here. If we look at this background page we can see we have this audio element just there which will be a problem. So what we're going to do instead is create a new file which is called off-screen.html and then we'll move both of these into there like this. We can get rid of our background.html just delete that. So then what we're going to do is go back to our manifest just take another look. So you can see here we don't need this as our service worker. So we're going to do exactly what we did last time and create a new service worker file which we'll come back to. I can spell. So let's go back into here. That'll be service worker.js. So now this will run but it won't actually play the music. So if we just go into here we can see that we have a few things that we'll need to adjust. So our service worker now let's rename this actually rather than background to document. And then we're going to here and change that. So let's just see what we have. So we have our service worker and we have a document. So what this is basically doing is listening for messages and then playing or pausing based on the message that was passed in. So if we look at the pop-out you can see that's what it's trying to do. This is going to send a message in here. So based on the video we did last time you can see all we basically need to do is register that off-screen document and go from there. So to do that we're going to go back into our manifest and we need to add a permission like this. And we just want to use the permission off-screen. This gives us access like we saw to actually use the off-screen documents. So then what we need to do is we can go into our service worker and we're going to use essentially exactly the same function that I used in my last video here to create off-screen element. So as soon as we have this here we're just going to call it at the bottom to create off-screen. So what we have now is as soon as extension is created we're going to be basically building our off-screen document. So let's go ahead and test this first and see what we have, see if we get any errors. So we can see how we're working with our off-screen document. So you can see here this matches up the same. We're going to be creating an off-screen document here. If we already have one, I'm just going to exit out. And then as we mentioned before, the other video goes into a little bit more detail about this. These are different types of reasons you can use an off-screen document. So again let's test this now and see what happens when we run it. Okay so you can see we have one error here which is based on the permission. Actually that's why we have that type of permission rather than permissions, which is something I see happen quite a lot. So anyway we'll put that in there. We're going to clear all these errors. We're going to refresh. So what we can see here is that we're running this in the, what version of Chrome have we got here? We're in version 108. So if we were to open Canary and try it there, let's see what we get. So first we're going to check what version we're in. So we're in 111 here. Okay so here we can see our extension has been added. If we go up here we can find it. Let's pin it. And then if we pick a track, yes, what we need to do is add a listener in our actual service worker that can forward our messages along. So we're going to do exactly the same thing that we did in that in that previous video. If you haven't seen it, I'll put a link in the description. But this is how the off-screen documents work and like we just saw there, it's only in Chrome Canary. So it's not a feature that's fully supported just yet, which is why Chrome have delayed the rollout of Manifest version 3. So as we can see this is our service worker and we're basically just going to, where have we got it, see our document just here. We're going to add a listener and we'll put that in here. So when these events are called, we're going to just send another message in to our off-screen document. So we're going to basically call these service worker play track, service worker pause track, and then this will send a message back to our off-screen document. So if we go into our pop-out, we're going to change this again like we just saw, service worker, service worker. But in here we're just going to, instead of putting this just there, this is going to then send a message to our off-screen document. So that'll be like that. This one, I'll just pause here like that. We just need to make sure though that we pass in the correct information here. So that'll be message, select track. We'll just log this just to be sure. So now if we look at what we have, so we can also create off-screen in here rather than just there. So each time we get in our messages, we're making sure that our off-screen document is awake and ready for this to come in. So let's just check through. So we have a pop-out, which is where the first message is going to come from. That's going to, on click of this button, is going to send a message to our service worker of play or pause. And then in our service worker, we're listening to these specific messages. And then we're passing one without this to our off-screen document, which is just here. So in the document, we're listening for these original messages, and then we're going to make those actions. So as we can see, everything else should have a query selector that matches up here, and that's all included. So let's give this a refresh and see what we get. Okay, so what we can see is there's a couple of changes we just need to make sure we have here. So when we're sending using this, we need to make sure we await this, and then just be sure to make sure that we're passing in message.track, not select track, because that was coming in from the actual... We set this just here. What we have now is a way to get from here. So again, make sure you await this so that we're not trying to access the document before it's actually on the page, or before it's been created. Then we're sending this in, which we'll get to here, and then that will use this track to then play the music. And what we should probably do here as well is make sure that this track name is available. So you could have an email or something that's like track one, track two, track three. If it's not one of these, show some sort of feedback back to the user that you're trying to play a track that doesn't exist. But again, this should be supported now, it should work. So let's go back to Canary and try and run this. We're going to refresh, go into here, try this one. I can't hear it. Oh, there we go. I don't know if you can hear that through here, but that's playing now. If we pause, it's pausing it if we change the track. Yeah, that one's playing. And then the first one. Yeah, that's playing. And if we close it, it's still able to play as we browse. And it's not going to be impacted between this because it's all in that off screen document rather than actually in the pop up itself. But we can pause it and get straight in. So that is the changes needed for the epic mode. So if we go back out of Canary now, so the next extension is this to do list here. So again, with this one, I'm thinking there's gonna be too many changes here. So if we look at the code we have already, you can see there's only three files. So I would say looking at this, all we really need to change is version two to version three, browser action to action. So for quick scan through here, check that we're not using any methods that have changed. This seems fine. This seems fine. Now, again, we should probably update this to use Chrome storage rather than local storage. Which is probably, I shouldn't have used that. That's what shows when you try and create extensions just in one, in one go on that video. But yeah, I'd recommend changing that, or even linking up to a database that could be a good follow up video for this one, actually. But yeah, so that seems to be all we'd need to change here. So let's try and run it and see what we get. So here it is, doesn't know there's any errors. We're going to go over here. Pin it, open it. So let's add an item. Okay, so we do have an error. So that's something we can look at. So can it read properties, no of push. So that sounds like the actual array doesn't exist, which is probably because we're using local storage here. So let's update this to use Chrome storage rather than local storage. So let's update this to work. So the first thing we need to do if we want to use Chrome storage now in manifest version three is we need to add the storage permission. So we're going to go into permissions, add storage. There we go. And now we're going to go over to here. So down here, where we actually do this, we're going to say instead, so comment out this out actually, so we can see what it was before. We're going to say item storage. So use the same exact name. So we have Chrome storage, local, get item, to do items, which doesn't actually sound right. So let's go into here. And we can just actually run this directly in here. So we'll say, Chrome. What we need to do first, actually, is comment this out. Let's just have this in here. And then we're going to go back and refresh this. Okay, up here. We're not going to actually try and run it yet. We're just going to access this from here. So Chrome storage, local. Is it get item or get? Yeah, it's just get. So if you pass in an empty object, it will return everything. What we can see is that we won't have anything in the response yet. Because we haven't saved anything yet. We're just going to update this now. Here, just to be get. And we're going to pass this in, like so. We can actually await these now, in manifest version three. Yeah, we're just gonna have this in the sync function. So what we're going to do first is just check that this is returning the right format. So what we'll find to begin with, is this, this will be empty, because obviously, we haven't run this before. So we need to make sure that we can handle whatever the format is empty. So we'll probably do something like item storage. And then actually have to keep it as a string for passing in. It's like that. So it's going to convert it into an empty array. But let's, we've saved that, at least let's go back here. And refresh, inspect. And then as we're doing before, it's going to move this across, we can see what is happening. So as we go back to the console, and we create a new item, record a video, save. Okay, so we can see that our object here is not a JSON. Okay, yeah, so we have to access this inside the element here. So you can see that's empty. So in this part here, we're just going to call it, we'll call this storage, that will be what we need. Now if we were to save items, to test that again in a second. But let's just connect this all together. So if we go down to the save function, which I'm guessing is down here, I've probably actually gone through and read this first. So we're going to do Chrome storage, local. Now the reason we're using local here is to keep it just on this one device. But again, with the other methods of Chrome storage, you can have it sync between devices. So if you're logging into the same Google account, on different devices, you can use this to sync it between each, which can be quite useful. But anyway, so what we have here is we're using Chrome storage local set. Again, we'll await this, just make sure to be using the right methods here. So again, if we go back to where we're calling this, we're calling it here, we need to wait that because otherwise fetch won't, that could be called before we get here. Do we use it anywhere else? This is going to try and update it. Yeah, we should probably await this one. So again, we need to change to be asynchronous here. And the same for delete, let's await that. So again, benefits of this. So yeah, we're going to be having that as an async function as well. So if we just look through, we should be okay with these changes. I'm rushing through this a little bit. So if you've got any questions, just drop a comment below. And I'll be sure to go into a bit more detail and take a look. So anyway, let's go into here now, clear this. So as we can see, if we test it now, and then save, we're getting that information. So as you can see in here, let's just go through these. So you can see it's encoded here, store, store. So if we come back in here, we can see, I added this, in fact, I should have recorded that part. We need on our fetch, we need to use the same logic here to actually pass it in. So we need to make sure that we're using the same name was using the variable name rather than the actual the key that we were getting it from. So you can see it's to do items, which we access that here from the array. And there we have it. And then we fall back obviously to the empty array. The same down here, we're actually load the items when we open the extension, we're grabbing it here from the array. And then we're going to be grabbing it here from, from to do items. So you can see we don't need that item storage anymore. I'll leave the console again, actually, so we can debug that and everything else. So item delete will come down here. Again, we need to update this part. So we're going to change items. Storage equals, we could do this. There is that and then we're going to say, pass item storage to do items. And then again, remember to make sure we fall back to that empty array. We're going to get rid of this. We also have it down here as well. So let's just recopy this. Can we do that? Yeah, we're going to recopy this bit and pass that here. So if we look through here, now, we can see the main change here. fumbled my way through it, but you can see that basically, it's just using chroma storage rather than local storage, which is a better change. We, we need it anyway. So if we refresh this now, come back to our to do's, we can delete them, add new ones, a new item. So that isn't completely working there. So we can mark this as done. What about if we close and reopen? Are they still done? Yeah, if we delete, open. I look like a bit of a bug there. So if we close, come back. Oh no, okay. Testing. Done. Delete. So yeah, okay, so that is now updated and using manifest version three. So that was the to do list. So the final one now is the the web scraper. So this one is a little bit more involved, because we're injecting content into the page using the content script, and there's a little bit more interaction there. But let's take a look first, like we did for all the others by starting with the manifest file. So as we can see, in here, again, the first thing we need to do change browser action to action, manifest version two to three. And then the content script should be okay. So we can save that. And actually, one thing we might need to do is change this to be host permission. Another thing I'd say, because reason that all URLs permission here is fine, if we're testing locally, but ideally, we'd want to add some type of onboarding. So we're not requesting such a strong permission, as soon as the user is installing the extension, because we can't in manifest version, version three, we can't guarantee that that will actually be provided, they might not have been asked that. So we want to make sure that we actually ask and request for the URL, the all URLs permission from a user action or something like that. But for now, and for this video, this is fine. Did I just change that? Action. There we go. Right. So we are going to now take a look at the pop out, which has a few different things going on in here. That looks okay. I can't remember writing this. Okay, so if we're looking through the message, that's okay. Sending a message to our active tab. So with this, we might actually be able to switch to just using the active tab permission. Because we're only really using this once the user has clicked onto that tab. So I think we need the content script. Other than once we've opened the, the pop up, or pop out. But we're going to keep that the same for now. So let's first do what we did with the others and run it and see if any more changes are needed. But like I say, with this one, I definitely recommend adding some type of onboarding to actually get that all URLs permission from a user action first. Okay, so here is our extension, we can see straight away. Permission all URLs is unknown or the URL is malformed. So the first thing we need to do is go in here and change this from permissions to host permissions. Like that. Now we're going to go back and refresh. Okay, so that's, the error is gone from there now. So we're going to go to my trusty site that I always use. Change where extension we have pinned and unpinned. Okay, so what we're going to do to test this is open up the, open up our DevTools down here, get our console, open, open up the scraper, we want to also inspect the actual pop up itself. So that can go just there. Give us a little bit of room. Okay, so now we're going to go into here and we can see that we can click different elements, we can enter values, and so on. So we're going to say wait 100 milliseconds. And then we're going to add a command to click, let's say, let's click this button here. So that's this link. So is there any other elements that have this? Okay, they all have this. Let's just try that first one. So we'll say, click this after 100 milliseconds. So you can see this is not a valid query selector. So do we actually need to pass this in? I obviously can't remember how I set this up. I think it might just be like that. So if we run, there we go, all commands have been run, and we've gone to the football page. So that is actually working with minimal changes. You can see here we're returning an empty array here as well. But this one is quite quick to adjust manifest version three. Now, seeing this makes me think that this can probably be improved quite a bit. It's quite confusing that we have this in here, which probably have different options that you can select, and different placeholder information based on the type of option you're selecting here. So if we wanted to save the value from that same command, if we run that now, let's see, no inner text, right, that's a link. I think this one might need to be a like a button, or like a, like one of these. So if we were to use this as a example, example query, and if we just put in this as input, it's about a there we go, you can see we updated that based on this. There's a few things that I probably should have done a little bit more research into what exactly that extension did. But you can see how the actual migration from manifest version two to three wasn't too, too difficult. Now, obviously, these extensions were all quite simple and straightforward. The most thing we needed to change, or the main thing we need to change was the manifest version and the pop up, you know, browser action to action, which isn't always going to be the case. If you're doing things with actual intercepting requests and things like that, it is going to be a little bit more complicated. If you're trying to run things with, let's say you've got remote code that you're using, you need to work out how to migrate that into other methods that aren't going to be relying on that as much. So even things like the libraries you might be using, that might need to change. You know, there's examples like extensions in using Gmail to add more interaction there, using things with the inbox SDK, that's now available, you completely can include in your extension. But you know, there's changes, things are changing a lot. So that makes it more complicated as well. But hopefully this video shows you a few more ways that you can migrate extensions. I'll be sure to save all of these changes as well. And put links to all of this updated code. So you can sort of compare the changes. But these were all quite simple extensions. So if you have any questions on how to migrate your extension, if there's a little bit more complexity involved, feel free to either leave a comment on this video or send me an email or DM me on Twitter, just let me know and I can take a closer look. And if you're happy to, I can share that in a future video as well. Or if you have any areas on actual making a more complicated migration, you want to take a closer look at, please do send me a message and I'll be happy to take a look. Anyway, thanks for watching this video and I'll see you in the next one.