Skip to content

Plugins

IMPORTANT

For CSS only modifications, see snippets

First, you will need the following:

FieldTypeDescriptionExample
namestringThe name of your plugin in Title CaseScroll Segments
nameCamelCasestringThe name of your plugin in camelCasescrollSegments
descriptionstringA brief description of what your plugin doesSegments the Schoolbox page into scrollable segments.
targets (optional)string[]An array of CSS selectors to wait for to load before injecting the plugin["#content", "#footer"]

Throughout this guide, you will see these between <angle brackets>. Replace them with the appropriate values.

Creating a Plugin

Boilerplate

  1. Append your plugin to the pluginConfig record in src/utils/storage/plugins.ts

    ts
    export const pluginConfig: Record<string, Types.PluginConfig> = {
      // ...
      <nameCamelCase>: {
        name: "<name>",
        description: "<description>",
        default: true, // whether your plugin should be enabled by default
      },
      // ...
    }

    You can also have settings for your plugin, this will be covered in the settings section.

  2. Create your plugin function in src/entrypoints/plugins with the name of your plugin in camelCase

    • If you are planning to include CSS, HTML, or Svelte alongside your TypeScript:
      1. Create a new directory in src/entrypoints/plugins called <nameCamelCase>
      2. Inside this folder, you can create a index.ts file for your TypeScript, and any other files you need (e.g. styles.css)
    • If you are only planning to include TypeScript:
      1. Create a new file in src/entrypoints/plugins called <nameCamelCase>.ts

    Now, in your TypeScript file, copy the following boilerplate:

    ts
    export default function init() { 
      defineStPlugin( 
        "<nameCamelCase>", 
        () => { 
          // Your code here
        }, 
        [<targets>], 
      ); 
    } 
  3. Import your plugin in src/entrypoints/plugins.content.ts

    ts
    // ...
    import <nameCamelCase> from "./plugins/<nameCamelCase>"; 
    
    export default defineContentScript({
      matches: ["<all_urls>"],
      runAt: "document_start",
      excludeMatches: EXCLUDE_MATCHES,
      async main() {
        // ...
        <nameCamelCase>(); 
      },
    });

Plugin Settings

In src/utils/storage/plugins.ts there is an optional settings field which can be used to define configurable settings components:

  • slider: select a numerical value between a minimum and maximum
    ts
    type Slider = {
      value: number;
      min: number;
      max: number;
    };
  • toggle: select a boolean value
    ts
    type Toggle = {
      toggle: boolean;
    }

NOTE

This list will be updated as new configurable options are introduced. If you require assistance or would like an input to be added, please open a GitHub issue or contact me.

Say we are developing a command palette plugin, and want to add a slider for the number of results shown in the popup. We can add the following code to our plugin definition:

ts
export const pluginConfig: Record<string, Types.PluginConfig> = {
  // ...
  <nameCamelCase>: {
    name: "<name>",
    description: "<description>",
    default: true,
    settings: { 
      maxResults: { 
        type: "slider", 
        name: "Max Results",  
        description: "How many search results are shown per query.", 
        default: { min: 1, max: 60, value: 10 }, 
      }, 
    }, 
  },
  // ...
}

Code!

Now that you have finished setting up the plugin storage, you can start working on the logic. This is located in src/entrypoints/plugins/<nameCamelCase>.ts or src/entrypoints/plugins/<nameCamelCase>/index.ts, depending on which one you chose.

You can put your code inside the arrow function, which will run whenever a Schoolbox page is loaded. For a simple example you can look at src/entrypoints/plugins/tabTitle.ts.

To access the value of storage items you can simply add the settings parameter to the arrow function.

ts
export default function init() {
  defineStPlugin(
    "<nameCamelCase>",
    () => { 
    (settings) => { 
      // your logic here ...

      // e.g. log the value of the maxResults setting
      logger.info(settings?.slider.maxResults); 

      // e.g. change all headings to accent colour
      document.querySelectorAll("h1").forEach((el) => el.style.color = "hsl(var(--ctp-accent))"); 
    }
  )
}