Over time, I realized this wasn't the greatest user experience because I need to leave my current context(calendar, webpage etc) to open this page in a new tab. I figured a
chrome extension would be great since I can view it from any page. So, I decided to build one.
My
primary goal is to use the same codebase to power both the webapp and the extension.
Step 1: Prep
Time Travel was originally built as a React app. That's a great starting point because it's plain JS and should "work" as a Chrome extension. We need to make a few changes to get it to load as an extension. The code is available here
here.
Update manifest.json
This is the absolute minimum to get Chrome to recognize this app as an extension. The official docs are
here.
{
"name": "Time Travel",
"version": "0.0.1",
"manifest_version": 2,
"browser_action": {
"default_popup": "index.html"
}
}
Load unpacked extension into ChromeRun
npm run build
to build the code. This will result in a
build
dir with the minified code. Follow the instructions
here to load the unpacked extension into Chrome. Now, when you try to run it, this is what you'd see.
Wait, why is it blank?!?!?
It's blank because there are errors. Use the extension error controls to debug the errors.
This is because of a built-in security feature of Chrome extension. You can read more about it here
here. Update the
manifest.json
and you're almost there.
{
"name": "Time Travel",
"version": "0.0.1",
"manifest_version": 2,
"browser_action": {
"default_popup": "index.html"
},
"content_security_policy": "script-src 'self' https://www.google-analytics.com https://www.googletagmanager.com 'sha256-542g0dYCGij9qXrDxQMMtqVv8KnMUzxA01jVlDKENEc=' 'sha256-OB2OtW2qkm5ZWV3zwAPKIevdEOFYyJQzKukfyVMEbUQ='"
}
Now, try to run it.
Wohoo - it works! It does not look perfect but still works!
So, what exactly is not working?
- The UI is too narrow
- Some styling is off
Not a shabby start.
Step 2: Extension specific update
I'm not going into details here since styling updates are UI specific. Since one of my key goals is to use the same codebase to power both the webapp and the extension. I plan to achieve that using the following code to identify where the app is running -
export function isExtension() {
return window.chrome && chrome.runtime && chrome.runtime.id !== undefined;
}
Using the above, I've made changes across the board to support extension specific updates. See
code There weren't too many. Here's the result -
Step 3: Submit for review
This is the boring part. Here's the list of items required
- Icons
- Product screenshots
- Marketing copy
Add this script to
package.json
to create the bundle.
"pack": "NODE_ENV=production npm run build && rm -f build.zip && zip -r build.zip build"