Skip to main content

Overview

The Olis Chrome Extension provides seamless browser integration, allowing users to access Olis features directly from their browser while browsing the web.

Technology Stack

Manifest V3

Latest Chrome extension API

TypeScript

Type-safe extension development

Webpack

Module bundling and optimization

React

UI components for popup and options

Project Structure

apps/chrome-extension/
├── src/
   ├── background/        # Service worker
   ├── content/           # Content scripts
   ├── popup/             # Extension popup UI
   ├── options/           # Options page
   └── shared/            # Shared utilities
├── public/
   ├── manifest.json      # Extension manifest
   └── icons/             # Extension icons
└── dist/                  # Build output

Development Setup

1

Navigate to the extension directory

cd apps/chrome-extension
2

Install dependencies

pnpm install
3

Build the extension

pnpm run build
This creates a production build in the dist/ directory.For development with hot reload:
pnpm run watch
4

Load in Chrome

  1. Open Chrome and navigate to chrome://extensions/
  2. Enable “Developer mode” (toggle in top right)
  3. Click “Load unpacked”
  4. Select the apps/chrome-extension/dist directory

Features

Context Menu Integration

Right-click on selected text to:
  • Ask Olis about the selection
  • Search with Olis
  • Add to knowledge base
  • Summarize content
// Example: Register context menu
chrome.contextMenus.create({
  id: "ask-olis",
  title: "Ask Olis: \"%s\"",
  contexts: ["selection"]
})

Page Content Extraction

Automatically extract relevant content from web pages:
  • Article text
  • Page metadata
  • Links and references
  • Code snippets

Quick Access Popup

Search

Quick search interface accessible via browser action

Chat

Mini chat window for quick questions

History

Recent queries and results

Settings

Extension configuration

Manifest Configuration

{
  "manifest_version": 3,
  "name": "Olis",
  "version": "0.1.0",
  "description": "Your AI assistant in the browser",

  "permissions": [
    "activeTab",
    "contextMenus",
    "storage"
  ],

  "host_permissions": [
    "http://localhost:8000/*"
  ],

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

  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "css": ["content.css"]
    }
  ],

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

Communication Architecture

Message Passing

// From content script to background
chrome.runtime.sendMessage({
  type: 'ASK_OLIS',
  payload: { query: 'What is this page about?' }
}, (response) => {
  console.log('Response:', response)
})

// In background service worker
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'ASK_OLIS') {
    handleQuery(message.payload).then(sendResponse)
    return true // Async response
  }
})

Storage Management

Use Chrome’s storage API for persistence:
// Save data
chrome.storage.local.set({ apiKey: 'your-key' })

// Retrieve data
chrome.storage.local.get(['apiKey'], (result) => {
  console.log('API Key:', result.apiKey)
})

// Sync across devices
chrome.storage.sync.set({ preferences: {...} })

Building for Production

1

Build the extension

pnpm run build
2

Test the build

  1. Load the extension from dist/ directory
  2. Test all features thoroughly
  3. Check console for errors
  4. Verify on different websites
3

Create a package

cd dist
zip -r olis-extension.zip .
Or use a packaging script:
pnpm run package
4

Prepare for submission

  • Create promotional images (1280x800, 640x400)
  • Write detailed description
  • Prepare privacy policy
  • Create demo video (optional)

Publishing to Chrome Web Store

1

Register as a developer

Visit Chrome Web Store Developer Dashboard and pay the $5 registration fee.
2

Upload your extension

  1. Click “New Item”
  2. Upload the ZIP file
  3. Fill in store listing details
  4. Add screenshots and promotional images
3

Submit for review

Review can take a few days to a week. You’ll be notified via email.

Best Practices

Performance

  • Minimize content script impact
  • Use event-driven architecture
  • Lazy load resources
  • Cache API responses

Security

  • Validate all input
  • Use HTTPS for API calls
  • Follow CSP guidelines
  • Handle sensitive data carefully

UX

  • Fast, responsive UI
  • Clear error messages
  • Intuitive interactions
  • Keyboard shortcuts

Compatibility

  • Test on multiple websites
  • Handle edge cases
  • Graceful degradation
  • Cross-browser support

Troubleshooting

Problem: Extension doesn’t appear in ChromeSolution:
  1. Check manifest.json for errors
  2. Verify all files referenced exist
  3. Look for errors in chrome://extensions/
  4. Reload the extension
Problem: Content script doesn’t run on pagesSolution:
// Check manifest matches
"content_scripts": [{
  "matches": ["<all_urls>"],  // Or specific patterns
  "js": ["content.js"],
  "run_at": "document_idle"   // Timing matters
}]
Problem: Cannot reach API serverSolution:
  1. Check host_permissions in manifest:
    "host_permissions": ["http://localhost:8000/*"]
    
  2. Verify CORS is configured on server
  3. Check network tab in DevTools
  4. Test API endpoint directly
Problem: Webpack build failsSolution:
# Clean and reinstall
rm -rf node_modules dist
pnpm install
pnpm run build

# Check for TypeScript errors
pnpm run type-check

Testing

Manual Testing

1

Load the extension

Load unpacked extension from dist/ directory
2

Test on various websites

  • News articles
  • Documentation sites
  • Social media
  • Web apps
3

Test all features

  • Context menu items
  • Popup functionality
  • Content extraction
  • API communication
4

Check console

Look for errors in:
  • Extension popup console
  • Background service worker console
  • Page console (for content scripts)

Automated Testing

// Example: Jest test for background script
import { handleQuery } from '../background/handlers'

describe('Background handlers', () => {
  test('handleQuery returns response', async () => {
    const response = await handleQuery({ query: 'test' })
    expect(response).toHaveProperty('answer')
  })
})

Next Steps