NextJS Chrome Extension: A Developer's Guide

published on 07 December 2023

It's clear most developers would agree that building Chrome extensions can be challenging, especially when incorporating modern frameworks like Next.js.

But with the right approach, you can leverage the power of Next.js to create feature-rich Chrome extensions more efficiently.

In this post, you'll get a comprehensive guide on Next.js Chrome extension development - from environment setup to deployment.

You'll see step-by-step code examples for building key components like background scripts, content scripts, options pages, and more using Next.js, TypeScript, and React. Plus, guidance on tapping into powerful Chrome APIs and bundling assets for publishing on the Chrome Web Store.

Launching Into NextJS Chrome Extension Development

NextJS is a popular JavaScript framework that can also be leveraged to build robust Chrome extensions. Using NextJS streamlines extension development with features like server-side rendering, easy page routing, and a rich ecosystem of libraries.

This guide will walk through the key benefits of using NextJS for Chrome extensions and provide actionable code samples to get started.

Accelerated Development with NextJS

NextJS offers numerous advantages over vanilla JavaScript or other libraries when developing Chrome extensions:

  • Seamless page routing - NextJS makes routing seamless between extension pages using the built-in Link component for navigation. No need to manually setup history or route handling.
  • Code splitting - Only load the JS and CSS required for each route, improving extension performance. NextJS handles code splitting automatically.
  • Streamlined data fetching - Leverage getStaticProps and getServerSideProps to pre-render data. No need to worry about client-side data hydration.
  • Rich ecosystem - Take advantage of the vast selection of third-party modules in the NextJS ecosystem like UI libraries.
  • TypeScript support- NextJS has first-class support for TypeScript, enhancing development speed.

By handling much of the complexity around routing, rendering, and data out of the box, NextJS gives developers more time to focus on building the extension functionality and UI.

Structuring a NextJS Chrome Extension

A NextJS Chrome extension follows a fairly standard project structure:

my-next-extension
├─ pages
│  └─ index.tsx
├─ public
│  └─ manifest.json  
├─ next.config.js
└─ package.json

The key aspects are:

  • pages - Contains NextJS page components that define each extension route.
  • public/manifest.json - Standard Chrome extension manifest file.
  • next.config.js - NextJS custom configuration.
  • package.json - Manages dependencies and scripts.

From this foundation, developers can build out additional functionality like options pages, background services, content scripts, etc.

Next Steps

With the basics covered, you're ready to kickstart building NextJS Chrome extensions. Some helpful next steps:

  • Check the NextJS Chrome Extension Boilerplate for a pre-configured starter kit
  • Learn how to integrate React component libraries like Chakra UI
  • Explore production building and distribution best practices
  • Implement CI/CD pipelines to automate extension delivery

NextJS unlocks a robust, scalable approach to Chrome extension development. Follow this guide to hit the ground running leveraging its capabilities!

Can I use Next.js for Chrome extension?

Yes, you can use Next.js to build Chrome extensions! next-chrome is a great starter project for bootstrapping a Chrome extension using Next.js.

Here's a quick overview of how to get started:

First, install next-chrome:

npm install next-chrome

Then generate a new Next.js app with next-chrome:

npx create-next-app my-extension --example next-chrome

This will scaffold out a Next.js app configured for Chrome extension development with next-chrome already setup.

The key things next-chrome provides:

  • Configured build output for the Chrome extension directory structure
  • Scripts for compiling the extension and opening Chrome with it loaded
  • Base components and pages for popup and options
  • Manifest configuration
  • TypeScript support

For example, the generated pages/popup/index.tsx page renders the popup UI:

export default function Popup() {
  return (
    <div>
      <h1>My Chrome Extension Popup</h1> 
    </div>
  )
}

And public/manifest.json handles the Chrome extension manifest.

Overall, next-chrome makes it super easy to start building a Chrome extension with Next.js and React. The project handles all the complex Chrome-specific setup for you out of the box!

Can I use React in Chrome extension?

You can use React for almost everything, right? Well, for Chrome extensions, it can be a bit more tricky than you might think, hence this guide. Create React App doesn't work with Chrome extensions straight out of the box. The reason for that is React uses in-line scripts, which violates Chrome security guidelines.

To use React in a Chrome extension, you need a build process that compiles the JSX and bundles all the React code into a single file rather than having separate files for each component. This avoids inline scripts.

Here is a quick guide to setting up a React and TypeScript Chrome extension using Vite build tool:

Prerequisites

  • Node.js installed
  • Basic understanding of React and Chrome extensions

Steps

  • Create a new folder for your project
  • Initialize a new NPM project
npm init vite@latest
  • Select react-ts template
  • Install Chrome extension libraries
npm install chrome-extension-async and chrome-extension-fs
  • Configure vite.config.js

  • Set build.rollupOptions.output to generate a single bundle file

  • Set build.emptyOutDir to true

  • Add Chrome extension config

  • Update public/manifest.json with extension details

  • Code your components in src folder

  • Build extension

npm run build
  • Load extension in Chrome from dist folder

And that's it! The key things to note are using Vite to bundle React code properly for a Chrome extension, configuring the manifest file, and installing Chrome extension libraries to use the API.

Let me know if you have any other questions!

What is Next.js and why it is used?

Next.js is a popular React framework that makes it easy to build server-rendered React applications. Here are some of the key benefits of using Next.js for your projects:

Server-Side Rendering

One of the main advantages of Next.js is that it handles server-side rendering (SSR) automatically. This means your pages will load faster for users, as the initial HTML is generated on the server. Next.js pre-renders each page, taking load off the client.

For example, here is what the initial render looks like with Next.js SSR:

function Page({ data }) {
  // Render data 
}

export async function getServerSideProps() {
  // Fetch data
  return { props: { data } }  
}

The getServerSideProps fetches data, and passes it to Page component as props. This happens on server before sending markup to client.

Easy Routing

Client-side routing can be complex to set up in React apps. With Next.js, routing works right out of the box using the pages directory structure.

For example, create pages/blog/first-post.js and it will be accessible at /blog/first-post. Clean URLs without messy routing config!

Built-in Optimizations

Next.js handles performance optimizations like code splitting automatically. It loads only code required for each page, speeding up site performance.

Features like ahead-of-time compilation support fast page loading. Next.js handles optimizing and bundling your application code with no extra config needed.

Vibrant Ecosystem

As a popular framework, Next.js benefits from a strong community. There is great documentation, plus many tutorials and open-source examples to learn from.

Integrating other tools like TypeScript or Tailwind CSS is simple. There are also starter kits and UI libraries specifically for Next.js sites.

Overall, Next.js removes much React boilerplate, while offering performance benefits and developer convenience. It's a great fit for sites where SEO and speed matter.

Can I build a Chrome extension?

As a developer, you can build a Chrome extension with Next.js. Here is a simple guide to get you started:

Prerequisites

  • Node.js installed
  • Basic knowledge of Next.js
  • Next.js project set up

Set up the manifest

Create a public/manifest.json file and configure it with metadata for your extension:

{
  "name": "My Next.js Extension",
  "version": "1.0.0",
  "manifest_version": 3,
  "action": {
    "default_popup": "pages/popup.js",
    "default_icon": "icon.png"
  }
}

This specifies the popup component and icon asset.

Create the popup page

Make a pages/popup.js page to render the popup UI:

export default function Popup() {
  return <h1>My Popup</h1> 
}

Style this however you like.

Package and install

Now build your Next.js app and load the extension in developer mode in Chrome:

npm run build
npm run export

Go to chrome://extensions, enable Developer mode, click Load unpacked and select the out folder.

The extension with popup should now work when you click its icon!

Next steps

Add more functionality like options pages, background services, content scripts and connecting to the Chrome APIs. Check the Chrome extension docs for more details.

Let me know if you have any other questions!

sbb-itb-5683811

Environment Setup: NextJS and TypeScript for Chrome Extensions

Setting up a robust development environment is key for building high-quality Chrome extensions with NextJS and TypeScript. This guide will walk through the essential steps for configuring your dev environment.

Installing NextJS with TypeScript Support

Let's start by scaffolding a NextJS project with TypeScript support using npx:

npx create-next-app my-extension --typescript

This will generate a NextJS app configured for TypeScript. Next, we'll add React dependencies:

yarn add react react-dom

With NextJS generating the framework code and React handling views and components, we've got a solid foundation for our Chrome extension.

Integrating Chrome Extension TypeScript Boilerplate

Instead of building a Chrome extension from scratch, we can leverage existing boilerplates to accelerate development. Let's integrate the chrome-extension-typescript-boilerplate from GitHub:

git clone https://github.com/chibat/chrome-extension-typescript-boilerplate.git
cp -r chrome-extension-typescript-boilerplate/* my-extension

This adds a pre-configured manifest.json, asset folder structure, and example background and content script foundation. Customize as needed!

Webpack and Babel for Chrome Extension Builds

Now let's optimize our webpack config and Babel presets specifically for bundled Chrome extension output.

In next.config.js:

module.exports = {
  webpack: (config) => {
    config.output.filename = 'static/js/[name].js'  
    return config
  }
}

And in .babelrc:

{
  "presets": ["@babel/env", "@babel/preset-react"]
}

This will transpile and bundle our Chrome extension source into an optimized production build.

Leveraging Manifest V3 and Service Workers

Finally, let's upgrade to Manifest v3:

"manifest_version": 3

And register a service worker to cache extension assets:

import {registerRoute} from 'workbox-routing';

registerRoute(/.*/, new CacheFirst());

That covers the essentials for integrating NextJS, TypeScript, and React to build Chrome extensions! With this robust foundation in place, you can start developing high-quality extensions.

NextJS Chrome Extension: Crafting the Project Skeleton

Overview of the key files and directories required for a NextJS Chrome extensions, leveraging a TypeScript and React foundation.

Designing the Manifest File with TypeScript

The manifest.json file defines the Chrome extension's metadata, permissions, and more. Here is an example manifest using TypeScript types:

import { ChromeManifest } from "chrome-types"; 

const manifest: ChromeManifest = {
  manifest_version: 3,
  name: "My Extension",
  version: "1.0",
  action: {
    default_popup: "dist/popup.html",
  },
  permissions: ["tabs"], 
  content_scripts: [
    {
      matches: ["https://*/*"],
      js: ["dist/contentScript.js"],
    }
  ]
};

export default manifest;

Key things to note:

  • Using the ChromeManifest interface brings intellisense and typesafety
  • The permissions array defines privileges
  • content_scripts injects JavaScript on web pages

Overall, TypeScript gives us strict types and robust tooling for the manifest.

TypeScript-driven Background Scripts

Background scripts listen for Chrome events in the background. For example:

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  // React to tab updates
});

Other things you can do:

  • React to downloads, bookmarks, history changes
  • Make cross-origin XHR requests
  • Directly interact with the browser

Overall, TypeScript allows writing scalable, maintainable background scripts.

Content Scripts and the DOM

Content scripts injected on pages can mutate the DOM:

document.body.innerHTML += '<p>Hello World</p>'; 

Other things you can do:

  • Read/write DOM nodes
  • Communicate with background scripts
  • Access cookies, local storage

TypeScript gives you end-to-end typing, linting and tooling for content scripts.

Options Pages in React

Options pages let users customize extensions. Using React allows creating feature-rich UIs with minimal effort:

function App() {
  return (
    <div>
      <h1>My Extension Options</h1> 
      <Toggle 
        defaultChecked={true}
        onChange={onToggleChange} 
      />
    </div>
  );
}

Benefits include:

  • Declarative programming model
  • Reusable component architecture
  • Virtual DOM optimization

In summary, React supersizes options pages with interactive widgets.

Harnessing Chrome APIs within a NextJS Context

Next.js offers a robust framework for building web applications using React. Combining it with the extensive APIs available in Chrome extensions can enable developers to create powerful and extensible tools. This guide will demonstrate accessing key Chrome extension functionality from within a Next.js context.

Leveraging chrome.tabs for Interactivity

The chrome.tabs API opens up valuable opportunities to interact with open browser tabs. For example, you can programmatically open, update, reorder, and control tab content. Here is an example leveraging TypeScript to open a new tab:

chrome.tabs.create({
  url: 'https://www.example.com' 
});

Additional capabilities include:

  • Updating tabs with new URLs dynamically
  • Executing scripts in the context of tabs using executeScript()
  • Controlling tab focus and position
  • Managing tab groups

Integrating these features into a Next.js application allows enabling user-initiated tab controls right from your components.

Persisting Data with chrome.storage

Chrome offers two storage options - sync and local. The chrome.storage API grants access to persist data in a key-value store either synchronized across signed-in devices or locally just to the current browser context.

Here is an example using the API with TypeScript:

interface ThemeSettings {
  theme: 'light' | 'dark';
}

const saveSettings = (settings: ThemeSettings) => {
  chrome.storage.sync.set(settings);
}

const getSettings = () => {
  chrome.storage.sync.get(['theme']); 
}

From within Next.js, you can leverage storage for state management, options settings, and more.

Additional Notable APIs

Other valuable Chrome APIs that integrate well with Next.js:

  • Notifications: Programmatically trigger system notifications
  • Runtime: Reload extensions, get platform info, and more
  • History: Read user browsing history
  • Cookies: Manage and modify cookies

The strong typing of TypeScript helps catch errors during compile-time when leveraging these APIs.

Putting it All Together

By harnessing Chrome extension APIs within Next.js, developers can build highly interactive web apps. For example, a productivity booster extension allowing users to open useful pages in new tabs, persist preferred settings in storage, and stay updated via notifications.

Next.js handling the frontend combined with Chrome APIs powering the backend creates a robust foundation. Adding TypeScript into the mix accelerates development and reduces bugs.

To learn more, check out these open source Next.js Chrome extension starter kits on GitHub:

  • next-chrome-typescript-boilerplate
  • next-chrome-extension-template

The Build Process: Assembling Your Chrome Extension

Assembling a Chrome extension using NextJS and TypeScript requires careful planning and execution to ensure your extension runs smoothly for users. This comprehensive guide will walk through the key steps of building, bundling, and preparing your extension for distribution in the Chrome Web Store.

Asset Bundling with Webpack for Chrome Extensions

Bundling your extension's assets properly is crucial for performance and compatibility. We'll use webpack to combine and optimize our TypeScript code, React components, stylesheets, images, and other resources into the necessary Chrome extension file structure.

First, install webpack and associated loaders:

npm install webpack webpack-cli --save-dev
npm install ts-loader css-loader file-loader --save-dev

Then configure webpack.config.js to set entry points and output directories per Chrome extension requirements:

module.exports = {
  entry: {
    background: './src/background.ts',
    contentScript: './src/contentScript.ts',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(jpg|png|gif|svg|pdf)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'images',
          },
        },
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
};

This handles transpiling TypeScript, loading CSS, and moving images into the dist folder properly.

Run webpack to bundle all assets before loading into Chrome. The result will be production-ready JS bundles separated by entry point along with optimized assets.

Designing Assets for the Chrome Web Store

To attract users, create polished icons, screenshots, and description copy before publishing your extension.

Icons

Chrome expects a 128x128px icon in .PNG format named icon.png to display in the Chrome Web Store and extensions toolbar. Use a simple, recognizable image relevant to your extension's purpose.

Screenshots

Submit at least 2 JPEG, PNG, or GIF screenshots showing your extension's functionality to include in the listing. Optimize images to avoid unnecessarily large file sizes.

Description

Write clear, compelling copy highlighting what your extension does and why users should download it. Include relevant keywords and what makes your extension unique. A good description can drive downloads and reviews!

Keeping these assets updated will enable your product page to engage users at every phase.

The Publishing Odyssey on Chrome Developer Dashboard

With code bundled and listing assets ready, it's time to ship your extension to the Chrome Web Store and user browsers!

First, sign in to Chrome Developer Dashboard and register as a developer if new. Click "Add new item" and select "Extension".

Upload or point to the generated dist folder with your extension's code. Chrome will analyze files and prompt you to complete any missing required assets.

With all checks passed, add listing details like name, description, images, category, etc. and set an initial status to "Draft". Review how the unpublished listing looks and test functionality by adding your extension via "Developer mode" in Chrome extensions settings.

When ready, switch the extension entry to "Published" to submit for public access and syncing across user browsers. Celebrate your published Chrome extension built with NextJS and TypeScript! Continuously monitor your item analytics, user reviews, and updates from Google to keep improving from here.

This end-to-end walkthrough should equip you to assemble, test, and distribute a polished custom Chrome extension using NextJS. Let us know if you have any other questions!

Embarking on Your NextJS Chrome Extension Adventure

NextJS offers developers an ideal framework for building robust Chrome extensions with React and TypeScript. By leveraging NextJS's powerful routing system and API routes, developers can create feature-rich extensions that integrate smoothly into the browser.

As you embark on building Chrome extensions with NextJS, keep these best practices in mind:

Use NextJS API Routes for Background Scripts

NextJS API routes execute on the server, making them perfect to run continuously in the background.

// pages/api/background.js

export default (req, res) => {
  // Perform background tasks 
}

Call the API route from your manifest file's background property.

Manage Component State with React

React's state and effects hooks help manage complex component logic and UI updates. For example, you can track extension popup open/closed state with React:

const [isOpen, setIsOpen] = useState(false);

useEffect(() => {
  // Toggle isOpen when popup opens/closes
}, []); 

Build with TypeScript

TypeScript brings type safety and tooling for large extensions. Make components reusable by exporting typed interfaces:

interface Props {
  title: string; 
}

export const Header = (props: Props) => // ...

NextJS and React offer an unparalleled developer experience for crafting Chrome extensions. Equipped with these tips, you're ready to build browser extensions that delight users. Happy coding!

Related posts

Read more

Built on Unicorn Platform