Frontend Development 13 min read

Building a Chrome Extension for Quick Account Switching and Management

This article explains how to design and implement a Chrome extension using React, Webpack, and JavaScript to store multiple login accounts, tag them, isolate environments, and provide one‑click login directly from the browser and VS Code, improving efficiency for testers, developers, and product teams.

政采云技术
政采云技术
政采云技术
Building a Chrome Extension for Quick Account Switching and Management

In many development workflows, repeatedly entering usernames and passwords across different test, pre‑release, and production environments wastes time. The article introduces a Chrome extension that extends the browser's built‑in password manager to enable fast account switching, isolation, and tagging.

Requirements

Support account entry and one‑click login to save input time.

Allow custom tags for each account with full CRUD operations.

Isolate accounts per environment to avoid cross‑contamination.

Provide an easy‑to‑use UI.

Design Overview

The solution is built as a Chrome Extension, which runs in a sandboxed environment and interacts with web pages via content scripts. The extension uses standard web technologies (HTML, JavaScript, CSS) and React for the UI.

Project Structure

.
├── README.md 
├── package-lock.json
├── package.json
├── src
│   ├── assets          # extension icons
│   ├── contentScript   # scripts that run in the page
│   ├── manifest.json   # extension manifest
│   └── popup           # popup UI
└── webpack.config.js

manifest.json

{
  "name": "Account Saver",
  "description": "zcy 账号管理小精灵~",
  "version": "1.0",
  "manifest_version": 2,
  "icons": {
    "16": "./assets/icon.png",
    "48": "./assets/icon.png",
    "96": "./assets/icon.png",
    "128": "./assets/icon.png"
  },
  "browser_action": {
    "default_icon": "./assets/icon.png",
    "default_title": "账号管理小精灵~",
    "default_popup": "/popup.html"
  },
  "permissions": ["tabs", "activeTab", "storage", "notifications"],
  "background": {"persistent": false, "scripts": ["./background.js"]},
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
  "content_scripts": [{
    "matches": ["http://*/*", "https://*/*"],
    "js": ["/popupListener.js"],
    "run_at": "document_idle"
  }]
}

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  context: path.resolve(__dirname, './src'),
  entry: {
    popup: './popup/index.js',
    background: './background/index.js',
    popupListener: './contentScript/popupListener.js',
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/',
    filename: '[name].js',
  },
  module: {
    rules: [
      { test: /\.css$/, use: ['style-loader', 'css-loader'] },
      { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            babelrc: false,
            presets: [require.resolve('@babel/preset-react'), require.resolve('@babel/preset-env')],
            plugins: ['@babel/plugin-proposal-class-properties'],
            cacheDirectory: true,
          },
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({title: 'popup', template: './popup/index.html', inject: true, chunks: ['popup'], filename: 'popup.html'}),
    new webpack.HotModuleReplacementPlugin(),
    new CleanWebpackPlugin(['./dist/', './zip/']),
    new CopyWebpackPlugin([
      { from: 'assets', to: 'assets' },
      { from: 'manifest.json', to: 'manifest.json', flatten: true },
    ]),
  ],
};

Core Code

Content Script

The content script injects a React component into pages that contain a username input field on the ZCY domain, creating a floating panel with saved accounts.

const { domain } = document;
const isZcy = domain.indexOf('zcy') !== -1;
const userDom = document.getElementsByName('username')[0];

if (isZcy && userDom) {
  const body = document.getElementsByTagName('body')[0];
  const panelWrapper = document.createElement('div');
  ReactDOM.render(
, panelWrapper);
  body.append(panelWrapper);
}

One‑Click Login Logic

When a user selects an account, the script fills the username and password fields, dispatches input events, and programmatically clicks the login button.

const usernameDom = document.getElementById('username');
const passwordDom = document.getElementById('password');
const { accountList } = this.state;
const { username, password } = accountList.find(item => item.username === handleUsername);

const evt = new Event('input', { bubbles: true });
usernameDom.value = username;
usernameDom.dispatchEvent(evt);
passwordDom.value = password;
passwordDom.dispatchEvent(evt);

const loginBtn = document.getElementsByClassName('login-btn')[0];
loginBtn.click();

Development Helpers

Because hot‑module replacement does not work for extensions, developers must reload the extension manually via chrome://extensions/ or use the “Extensions Reloader” Chrome Web Store tool.

Future Plans

Persist account data to a backend service to avoid loss.

Share account data with a VS Code plugin for local proxy usage.

Add a unified login feature to bridge user identities across browsers.

Introduce business‑group isolation to prevent tag mixing.

Enable multi‑account login for testing scenarios.

The roadmap also includes an E‑R diagram for the data model and references to the official Chrome Extensions documentation.

JavaScriptreactchrome extensionwebpackAccount Management
政采云技术
Written by

政采云技术

ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.