Reading/Web/Content Discovery Experiments/Chrome Extension

Overview

The Web Experiments Browser Extension is a tool developed by the Web team at the Wikimedia Foundation to test and gather feedback on experimental features for Wikipedia. It is designed to accommodate multiple experiments, allowing for quick iteration and feedback gathering.

Currently, the extension includes the Empty Search State experiment (T370521), but future experiments can easily be added. This extension targets desktop Wikipedia but can be adjusted for mobile use if necessary.

Current Experiment: T370521 - Empty Search State on Vector 2022

This experiment focuses on tracking user behavior when no search suggestions are available in the Vector 2022 skin. The experiment logs three key events:

  • Enabled Event: Logs when the extension is enabled on a page view.
  • Impression Event: Logs when empty search suggestions are displayed.
  • Click Event: Logs when users click on one of the empty search suggestions.

The extension is also built to fetch related search suggestions using the morelike feature of CirrusSearch via the RelatedPagesGateway.

Clone the Repository

Run the following command in your terminal to clone the repository

git clone https://gitlab.wikimedia.org/repos/web/web-experiments-extension.git

System Requirements

To build and run this extension, ensure that the following are installed:

  • Node.js: Version 18 or higher
  • npm: Version 8 or higher
  • Chrome: Version 127 or higher

Quickstart Guide

1. Install Dependencies

Run the following command in your terminal to install the necessary dependencies:

npm install

2. Build the Extension

After installing dependencies, build the extension for development:

npm run dev

This will create a development version of the extension in the /dist directory.

3. Load the Extension in Chrome

  1. Open Chrome and navigate to chrome://extensions/.
  2. Enable Developer Mode by toggling the switch in the top-right corner.
  3. Click Load unpacked.
  4. Select the /dist directory.

4. Development Workflow

While developing, Vite will run in the background, allowing hot reloads when changes are made to files in the /src folder. If the extension does not reload automatically:

  • Keep the Chrome DevTools open.
  • Manually reload the extension via the "Reload" button on the Chrome Extensions page.

File Overview and Detailed Functionality

1. Vite Configuration (vite.config.js)

The vite.config.js file configures the dev server and production build for the extension. It uses the Vite plugin for Vue and crx.js to bundle the extension with Vue support.

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { crx } from '@crxjs/vite-plugin';
import manifest from './manifest.json';

export default defineConfig({
    plugins: [
        vue(),
        crx({ manifest })
    ],
    build: {
        outDir: process.env.BUILD_OUT_DIR || 'dist'
    }
});

2. Manifest File (manifest.json)

Defines the basic structure of the Chrome extension, including version, icons, and the injector.js script. The injector.js content script injects JavaScript into the pages specified under matches.

{
    "manifest_version": 3,
    "name": "__MSG_extension_name__",
    "version": "0.0.1",
    "description": "__MSG_extension_description__",
    "default_locale": "en",
    "icons": {
        "128": "src/assets/icons/wikipedia-logo-128.png"
    },
    "content_scripts": [
        {
          "js": ["src/content_scripts/injector.js"],
          "matches": ["https://*.wikipedia.org/*", "http://localhost:8080/*"],
          "exclude_matches": ["https://www.wikipedia.org/*"]
        }
    ]
}

3. Injector Script (injector.js)

The injector.js file is a content script injected into specified Wikipedia pages. It creates a script tag that loads the main experiment logic (main.js) onto the page, allowing interaction with MediaWiki utilities like mw.load and mw.track.

const scriptTag = document.createElement('script');
scriptTag.src = chrome.runtime.getURL(main);
scriptTag.setAttribute('defer', 'defer');
scriptTag.setAttribute('type', 'module');
document.body.appendChild(scriptTag);

4. Main Experiment Logic (main.js)

The core functionality of the experiment is handled here. It initializes a Vue.js application and fetches related search suggestions using the RelatedPagesGateway API. The experiment tracks when the search input box is available and logs events using mw.track.

import { createApp } from 'vue';
import App from './App.vue';
import RelatedPagesGateway from './RelatedPagesGateway';

// Observer to detect when the search box is ready
const searchBoxObserver = new MutationObserver((mutations) => {
    for (const mutation of mutations) {
        if (mutation.target.classList.contains('cdx-typeahead-search')) {
            startApp(window.mw);
            searchBoxObserver.disconnect();
            break;
        }
    }
});

The experiment tracks:

  • Enabled Events: Triggers when the extension is loaded on a page.
  • Impression Events: Triggers when search suggestions are shown.
  • Click Events: Triggers when a user interacts with suggestions.

The RelatedPagesGateway fetches related search results using the CirrusSearch API and processes them into a format that can be displayed in the Vue app.

function RelatedPagesGateway(api, currentPage, editorCuratedPages, useCirrusSearch, onlyUseCirrusSearch, descriptionSource) {
    this.api = api;
    this.currentPage = currentPage;
    this.useCirrusSearch = useCirrusSearch;
    this.descriptionSource = descriptionSource;
}

Future Experiment Support

The Web Experiments extension is designed to handle multiple experiments by adding new scripts and content logic. Future experiments can be easily included by extending the existing structure and adding new handlers to main.js.

FAQ

1. What if the extension doesn’t reload automatically?

  • Keep Chrome DevTools open or manually reload the extension from the "Details" page in the Chrome Extensions Manager.

2. Can this extension be used for mobile Wikipedia?

  • While the extension is primarily built for desktop, it can be adjusted to target mobile domains if needed.