Template Overview
Methexis is a starter template for creating a Chrome browser extension. Here is what the starter template does:

<div>
is added by inject/autoload/autoload.js
and styled by inject/autoload/autoload.css
when the site is navigated to
popup/popup.html
, which loads code in popup/popup.js
that can modify the page further
inject/action/action.js
and inject/action/action.css
(injected from popup/popup.js
)Getting Started
Repository
You can follow the guide below or clone the repo and explore on your own:
git clone https://github.com/Mierenga/methexis
Project Tree
.
├── img # images extension needs to access
│ └── logo.png
├── inject # modules of css and js files that can be injected into a page
│ ├── action # module injected by popup.js
│ │ ├── action.css
│ │ └── action.js
│ └── autoload # module injected whenever the user's URL matches the target in manifest.json
│ ├── autoload.css
│ └── autoload.js
├── manifest.json # the main registration of the extension; connects everything together
├── popup # page displayed underneath extension icon when clicked in the browser toolbar
│ ├── popup.html
│ └── popup.js
└── rules.js # logic for when to allow interactions with the popup, etc.
5 directories, 9 files
Manifest
Add a manifest.json
file
- Grant permissions and specify which scripts will run under different conditions
{
"name": "Methexis",
"version": "0.0.01",
"icons": {
"128": "img/logo.png"
},
"description": "An originally Ancient Greek form of theatre in which the audience participates and improvises.",
"permissions": [
"activeTab", // Grant extension access to whatever is the active tab in a browser window
"declarativeContent" // Grant extension the ability to declare content that can be injected into pages it can access
],
"background": {
"scripts": [ "rules.js" ], // Run extension's setup rules for on the window (see example below)
"persistent": false
},
"
manifest.json
Logo
Add a logo
Add your logo image to the location referenced in
icons
sections of manifest.json
, e.g., img/logo.png
Page Rules
Add a rules.js
file
- Runs in a background context (apart from the popup context and in-page content context).
- Adds a rule that allows the
ShowPageAction
when the current URL host matchesexample.com
ShowPageAction
opens the popup page when extension icon is clicked in the Chrome toolbar
- Popup page file is specified in
manifest.json
under"page_action": { "default_popup": "popup/popup.html" }
chrome.runtime.onInstalled.addListener(() => {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
chrome.declarativeContent.onPageChanged.addRules([{
conditions: [
// Actions below are allowed when these conditions are met
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostEquals: 'example.com' },
}),
],
actions: [
// Allow the extension icon button in the Chrome toolbar to show
// popup/popup.html when clicked
new chrome.declarativeContent.ShowPageAction(),
],
}]);
});
});
rules.js
Action Popup View
Add a popup/popup.html
file
- Displayed when the user clicks the extension icon in the browser toolbar
- The code in
rules.js
controls which web domains the popup activates for
- Loads the script at
popup/popup.js
<!DOCTYPE html>
<html>
<head>
<style>
body {
width: 100%;
height: 100%;
margin: 10px;
background: black;
color: white;
}
</style>
<!-- script paths are relative to this (popup.html) file -->
<script src="popup.js"></script>
</head>
<body>
Hello, World!
</body>
</html>
popup/popup.html

Action Popup Script
Add a popup/popup.js
file
- Immediately injects a JavaScript and CSS file into the current tab that will be given access to the
document
of the web page.
- Other scripts and libraries can be injected here or when a user interacts with the
popup/index.html
page to trigger additional actions
/**
* Open the active tab in the current Chrome window (using the permission established in the manifest.json)
* and inject a list of .css and .js files asynchronously, resolving when all files are injected (order unknown)
* @param {{ js: string[], css: string[] }} files
* @return Promise
*/
async function injectFiles(files) {
const [ tab ] = await new Promise(resolve => chrome.tabs.query({active: true, currentWindow: true}, resolve));
files.css && await Promise.all(files.css.map(file => new Promise(resolve => chrome.tabs.insertCSS(tab.id, { file: file }, resolve))));
files.js && await Promise.all(files.js.map(file => new Promise(resolve => chrome.tabs.executeScript(tab.id, {file: file }, resolve))));
}
(async () => {
// Load any dependencies first
await injectFiles({
js: [
// Add any scripts/libraries you want to inject into the extension environment (to be called from the main injected script).
// Inside these scripts, you can store items for later using by setting them as a property somewhere on the window object,
// as is common with many front-end JavaScript libraries.
],
css: [
// Add stylesheets that will be applied to the shared DOM for current and future elements
'inject/action/action.css',
],
});
// Run your injection action scripts' main entry point
await injectFiles({
js: [ 'inject/action/action.js' ],
});
})();
popup/popup.js
Injected Autoload Script
Add an inject/autoload/autoload.js
file
- Registered in
manifest.json
to be injected whenever the user's URL changes to*://example.com/*
// You can access and modify the document of the page you are extending
(() => {
const hostDiv = document.getElementsByTagName('div')[0]
const extensionDiv = document.createElement('div');
extensionDiv.id = 'extension-container';
extensionDiv.innerText = 'This box was added by a browser extension automatically when you visited this site.'
hostDiv.appendChild(extensionDiv);
})();

Injected Autoload Styles
Add an inject/autoload/autoload.css
file
- Registered in
manifest.json
to be injected whenever the user's URL changes to*://example.com/*
#extension-container {
background: rgb(255, 208, 0);
border: 2px solid black;
border-radius: 4px;
}
inject/autoload/autoload.css
Injected Action Script
Add an inject/action/action.js
file
- Injected by
popup/popup.js
whenever the user click's the extension icon in the browser toolbar (and there's a matchingPageStateMatcher
condition inrules.js
)
// You can access and modify the document of the page you are extending
(() => {
const heading = document.getElementsByTagName('h1')[0];
heading.innerText = 'This Heading Was Changed By A Browser Extension When You Clicked It\'s Icon';
})();
inject/action/action.js

Injected Action Styles
Add an inject/action/action.css
file
- Injected by
popup/popup.js
whenever the user click's the extension icon in the browser toolbar (and there's a matchingPageStateMatcher
condition inrules.js
)
h1 {
color: rgb(206, 18, 90);
}
inject/action/action.css
methexis • Noun • An originally Ancient Greek form of theatre in which the audience participates and improvises. • The relation between a particular and a Platonic form.