Chrome Extension Extension Onboarding — Best Practices
6 min readExtension Onboarding Patterns
User onboarding is critical for Chrome extensions to ensure users understand and adopt key features. This document covers proven onboarding patterns that improve user engagement and reduce early churn.
First Install Detection
Use chrome.runtime.onInstalled to detect first-time installation:
chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
// First-time install - start onboarding
chrome.storage.local.set({ onboardingCompleted: false });
openOnboardingPage();
} else if (details.reason === 'update') {
// Extension updated - show what's new
handleUpdate(details.previousVersion);
}
});
function openOnboardingPage() {
chrome.tabs.create({ url: 'onboarding.html' });
}
Welcome Page
Open an onboarding tab immediately after first install. The welcome page should:
- Clearly state the extension’s value proposition
- Provide a brief overview of core features
- Include a “Get Started” button to begin setup
// In onboarding.html
document.getElementById('getStarted').addEventListener('click', () => {
startSetupWizard();
});
Step-by-Step Setup Wizard
Guide users through key features with a multi-step wizard:
- Introduction - What the extension does
- Permissions - Explain and request necessary permissions
- Configuration - Set initial preferences
- Tutorial - Quick walkthrough of main features
- Completion - Confirmation and tips
Permission Requests During Onboarding
Always explain why each permission is needed before requesting:
const permissionRationale = {
'tabs': 'We need access to tabs to help you manage your workflow',
'storage': 'Storage permission saves your preferences across sessions',
'activeTab': 'ActiveTab lets us assist with the current page you're viewing'
};
function requestPermissionWithExplanation(permission, rationale) {
showExplanationModal(permission, rationale);
// Then request the actual permission
chrome.permissions.request({ permissions: [permission] });
}
Feature Highlights & Tooltips
Use tooltip-style overlays to highlight new features:
function showFeatureTour(steps) {
let currentStep = 0;
function nextStep() {
if (currentStep >= steps.length) {
endTour();
return;
}
const step = steps[currentStep];
highlightElement(step.selector, step.message);
currentStep++;
}
return { nextStep, endTour };
}
Interactive Tutorials
In-extension guided tours help users learn by doing:
- Highlight UI elements sequentially
- Provide contextual instructions
- Allow users to practice each step
- Include “Next” and “Skip” buttons
Settings Initialization
Set sensible defaults, then allow customization:
const defaultSettings = {
theme: 'light',
notifications: true,
autoSave: true,
shortcut: 'Ctrl+Shift+E'
};
function initializeSettings() {
chrome.storage.sync.get(defaultSettings, (result) => {
if (chrome.runtime.lastError) {
// First run - set defaults
chrome.storage.sync.set(defaultSettings);
}
});
}
Pin Extension Prompt
Remind users to pin the extension for easy access:
function showPinPrompt() {
// Check if already pinned
chrome.action.isPinned((isPinned) => {
if (!isPinned) {
showModal('Pin Extension',
'For the best experience, pin this extension to your toolbar.');
}
});
}
Keyboard Shortcut Setup
Display current shortcuts and link to shortcut settings:
function displayShortcuts() {
chrome.commands.getAll((commands) => {
const shortcuts = commands.map(cmd =>
`${cmd.name}: ${cmd.shortcut || 'Not set'}`
);
renderShortcutList(shortcuts);
});
}
// Link to chrome://extensions/shortcuts
document.getElementById('shortcutSettings').href =
'chrome://extensions/shortcuts';
Skip Option
Always allow users to skip onboarding:
function skipOnboarding() {
chrome.storage.local.set({
onboardingCompleted: true,
skippedAt: Date.now()
});
redirectToMainPage();
}
Progress Tracking
Store completion status in storage:
function completeOnboarding() {
chrome.storage.local.set({
onboardingCompleted: true,
onboardingCompletedAt: Date.now(),
onboardingVersion: chrome.runtime.getManifest().version
});
}
function checkOnboardingStatus(callback) {
chrome.storage.local.get('onboardingCompleted', (result) => {
callback(result.onboardingCompleted);
});
}
Returning User Detection
Distinguish between new installs and updates:
chrome.runtime.onInstalled.addListener((details) => {
switch (details.reason) {
case 'install':
showNewUserOnboarding();
break;
case 'update':
showWhatsNew(details.previousVersion);
break;
case 'chrome_update':
// Handle browser update
break;
}
});
A/B Testing Onboarding Flows
Test different onboarding approaches:
function assignOnboardingVariant() {
const variants = ['wizard', 'video', 'interactive'];
const variant = variants[Math.floor(Math.random() * variants.length)];
chrome.storage.local.set({ onboardingVariant: variant });
return variant;
}
Related Patterns
- User Onboarding Guide - Detailed onboarding strategies
- Permission Gating - Best practices for requesting permissions
- Extension Updates - Handling updates and migrations
- A/B Testing Patterns - Testing different onboarding approaches
- Feature Flags - Toggle features during onboarding
- Remote Config - Dynamic configuration without updates
-
Crash Reporting - Monitor onboarding errors
Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.