Skip to content

Basic Integration

A minimal ExtensionLogin integration for Chrome extensions.

Overview

This example shows the simplest way to add user identification to your extension.

Project Structure

my-extension/
├── manifest.json
├── background.js
├── popup.html
├── popup.js
└── node_modules/
    └── extensionlogin/

Step 1: Manifest Configuration

json
{
  "manifest_version": 3,
  "name": "My Extension",
  "version": "1.0.0",
  "description": "A simple extension with user login",

  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },

  "background": {
    "service_worker": "background.js",
    "type": "module"
  },

  "permissions": [
    "storage"
  ],

  "host_permissions": [
    "https://api.extensionlogin.com/*"
  ]
}

Step 2: Background Script

Initialize ExtensionLogin in the background service worker:

javascript
// background.js
import ExtensionLogin from 'extensionlogin';

// Create the ExtensionLogin client
const extLogin = ExtensionLogin('el_live_your_api_key_here');

// Start the background service
// This sets up message handlers for popup communication
extLogin.startBackground();

// Listen for user login events
extLogin.onLogin.addListener((user) => {
  console.log('[Background] User logged in:', user.email);
});

// Listen for user logout events
extLogin.onLogout.addListener(() => {
  console.log('[Background] User logged out');
});

console.log('[Background] ExtensionLogin initialized');

Step 3: HTML Structure

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>My Extension</title>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    body {
      width: 320px;
      padding: 20px;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      background: #f5f5f5;
    }

    h1 {
      font-size: 20px;
      margin-bottom: 16px;
      color: #1a1a1a;
    }

    .form-group {
      margin-bottom: 12px;
    }

    label {
      display: block;
      margin-bottom: 4px;
      font-size: 14px;
      font-weight: 500;
      color: #333;
    }

    input {
      width: 100%;
      padding: 10px 12px;
      border: 1px solid #ddd;
      border-radius: 6px;
      font-size: 14px;
    }

    input:focus {
      outline: none;
      border-color: #3b82f6;
    }

    button {
      width: 100%;
      padding: 12px;
      background: #3b82f6;
      color: white;
      border: none;
      border-radius: 6px;
      font-size: 14px;
      font-weight: 500;
      cursor: pointer;
      margin-top: 8px;
    }

    button:hover {
      background: #2563eb;
    }

    button:disabled {
      background: #9ca3af;
      cursor: not-allowed;
    }

    .message {
      margin-top: 12px;
      padding: 10px;
      border-radius: 6px;
      font-size: 14px;
    }

    .message.success {
      background: #d1fae5;
      color: #065f46;
    }

    .message.error {
      background: #fee2e2;
      color: #991b1b;
    }

    .user-info {
      text-align: center;
    }

    .user-info h2 {
      font-size: 18px;
      margin-bottom: 8px;
    }

    .user-info p {
      color: #666;
      margin-bottom: 16px;
    }

    .hidden {
      display: none;
    }
  </style>
</head>
<body>
  <!-- Login Form -->
  <div id="login-view">
    <h1>Welcome</h1>

    <div class="form-group">
      <label for="email">Email</label>
      <input type="email" id="email" placeholder="[email protected]">
    </div>

    <div class="form-group">
      <label for="name">Name (optional)</label>
      <input type="text" id="name" placeholder="John Doe">
    </div>

    <button id="submit-btn">Get Started</button>

    <div id="message" class="message hidden"></div>
  </div>

  <!-- User Dashboard -->
  <div id="user-view" class="user-info hidden">
    <h2 id="user-name">Welcome!</h2>
    <p id="user-email"></p>
    <button id="logout-btn">Sign Out</button>
  </div>

  <script type="module" src="popup.js"></script>
</body>
</html>

Step 4: JavaScript Implementation

javascript
// popup.js
import ExtensionLogin from 'extensionlogin';

// Create ExtensionLogin client
const extLogin = ExtensionLogin('el_live_your_api_key_here');

// DOM Elements
const loginView = document.getElementById('login-view');
const userView = document.getElementById('user-view');
const emailInput = document.getElementById('email');
const nameInput = document.getElementById('name');
const submitBtn = document.getElementById('submit-btn');
const logoutBtn = document.getElementById('logout-btn');
const messageEl = document.getElementById('message');
const userNameEl = document.getElementById('user-name');
const userEmailEl = document.getElementById('user-email');

// Check for existing user on popup open
async function init() {
  const user = await extLogin.getUser();
  if (user) {
    showUserView(user);
  } else {
    showLoginView();
  }
}

// Handle login
submitBtn.addEventListener('click', async () => {
  const email = emailInput.value.trim();
  const name = nameInput.value.trim();

  // Validate
  if (!email) {
    showMessage('Please enter your email', 'error');
    return;
  }

  // Disable button during request
  submitBtn.disabled = true;
  submitBtn.textContent = 'Please wait...';

  try {
    const result = await extLogin.identify({
      email,
      name: name || undefined
    });

    if (result.success) {
      // Get the user data
      const user = await extLogin.getUser();
      showUserView(user || { email, name });
    } else {
      showMessage(result.error || 'Something went wrong', 'error');
    }
  } catch (error) {
    showMessage('Connection error. Please try again.', 'error');
  } finally {
    submitBtn.disabled = false;
    submitBtn.textContent = 'Get Started';
  }
});

// Handle logout
logoutBtn.addEventListener('click', async () => {
  await extLogin.logout();
  showLoginView();
});

// UI Helpers
function showUserView(user) {
  loginView.classList.add('hidden');
  userView.classList.remove('hidden');

  userNameEl.textContent = `Welcome, ${user.name || 'User'}!`;
  userEmailEl.textContent = user.email;
}

function showLoginView() {
  userView.classList.add('hidden');
  loginView.classList.remove('hidden');

  emailInput.value = '';
  nameInput.value = '';
  messageEl.classList.add('hidden');
}

function showMessage(text, type) {
  messageEl.textContent = text;
  messageEl.className = `message ${type}`;
}

// Initialize
init();

Step 5: Build Configuration

Using Webpack

javascript
// webpack.config.js
const path = require('path');

module.exports = {
  entry: {
    popup: './popup.js',
    background: './background.js'
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  mode: 'production'
};

Using Rollup

javascript
// rollup.config.js
export default [
  {
    input: 'popup.js',
    output: {
      file: 'dist/popup.bundle.js',
      format: 'iife'
    }
  },
  {
    input: 'background.js',
    output: {
      file: 'dist/background.bundle.js',
      format: 'iife'
    }
  }
];

Using Vite

javascript
// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        popup: 'popup.html',
        background: 'background.js'
      },
      output: {
        entryFileNames: '[name].js'
      }
    }
  }
});

Without a Bundler

If you prefer not to use a bundler, use the CDN:

html
<script src="https://cdn.jsdelivr.net/npm/extensionlogin@latest/dist/extensionlogin.min.js"></script>
<script>
  // ExtensionLogin is available as a global
  const extLogin = window.ExtensionLogin('el_live_your_api_key_here');

  // ... rest of your code using extLogin
</script>

Testing

  1. Load your extension in Chrome:

    • Go to chrome://extensions
    • Enable "Developer mode"
    • Click "Load unpacked"
    • Select your extension folder
  2. Click the extension icon to open the popup

  3. Enter an email and click "Get Started"

  4. Verify the user appears in your ExtensionLogin dashboard

Next Steps

Built for Chrome Extension Developers