mcpField
C
content-script-developer

content-script-developer

github.com/shipshitdevDevelopment38177 installsUpdated 2d ago
Repository

About content-script-developer

A development skill for building browser-extension content scripts that read page state or inject UI. It focuses on safe, idempotent behavior and handling dynamic pages without blocking the main thread.

Key features

  1. 01Safe UI injection
  2. 02Scoped styles and shadow roots
  3. 03SPA and DOM change handling
  4. 04Throttled MutationObserver patterns
  5. 05Background messaging and storage

Use cases

  1. 01Adding extension UI to third-party pages
  2. 02Reading state from dynamic web pages
  3. 03Preventing duplicate UI after SPA navigation

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/shipshitdev/skills --skill content-script-developer

After installing, type/content-script-developerin Claude Code to confirm it loaded.

Bundled filesplugin.json

Details

From the project README

Content Script Developer

When to Use

  • Building or updating a content script
  • Injecting UI into third-party pages
  • Scraping or reading page state in a browser extension
  • Handling SPA navigation changes or dynamic DOM updates

Core Constraints

  • Content scripts run in an isolated world; page JS scope is not shared.
  • Avoid polluting the host page (global styles, conflicting IDs/classes).
  • Be idempotent: injection should not duplicate on re-run.
  • Prefer robust selectors over brittle class chains.
  • Never block the main thread; throttle observers and event handlers.

Workflow

1) Understand the Target Page
  • Identify stable anchors (data attributes, IDs, landmark roles).
  • Note SPA navigation patterns (URL changes, DOM root swaps).
  • Decide what you need: read-only scrape vs UI injection.
2) Plan Injection Safely
  • Create a single root container for your UI.
  • Use a shadow root if CSS conflicts are likely.
  • Add styles with a unique prefix or scoped to your root.
  • Ensure cleanup hooks if the page swaps roots.
3) Handle Dynamic Pages
  • Use a MutationObserver for DOM changes.
  • Throttle work with requestAnimationFrame or debouncing.
  • Re-check anchors on navigation events.
4) Message and Store Data
  • Use chrome.runtime.sendMessage for background/service worker calls.
  • Use chrome.storage for persistent state.
  • Keep tokens or sensitive data in extension storage, not DOM.
5) Accessibility and UX
  • Keyboard-focusable UI elements.
  • Visible focus styles.
  • ARIA labels for controls.

Patterns and Snippets

Idempotent UI Injection
const ROOT_ID = 'ext-root';

export function ensureRoot() {
  let root = document.getElementById(ROOT_ID);
  if (root) return root;

  root = document.createElement('div');
  root.id = ROOT_ID;
  root.setAttribute('data-ext-root', 'true');
  document.body.appendChild(root);
  return root;
}
Safe Styling (Scoped)
const styleId = 'ext-style';

function injectStyles(css: string) {
  if (document.getElementById(styleId)) return;
  const style = document.createElement('style');
  style.id = styleId;
  style.textContent = css;
  document.head.appendChild(style);
}
MutationObserver with Throttle
let scheduled = false;
const observer = new MutationObserver(() => {
  if (scheduled) return;
  scheduled = true;
  requestAnimationFrame(() => {
    scheduled = false;
    // re-check anchors or update UI
  });
});

observer.observe(document.body, { childList: true, subtree: true });
Messaging to Background
async function fetchData(payload: Record<string, unknown>) {
  return await chrome.runtime.sendMessage({ type: 'FETCH_DATA', payload });
}

Reliability Checklist

  • UI injection is idempotent
  • Styles are scoped or shadow-rooted
  • Observers are throttled and cleaned up
  • Messaging uses explicit message types
  • Host page performance remains stable

Common Pitfalls

  • Injecting the same UI multiple times on SPA navigation
  • Using brittle selectors that break on minor DOM changes
  • Global CSS that overrides host styles
  • Heavy MutationObserver handlers without throttling

Notes

  • Prefer small, composable helpers over large one-off scripts.
  • Keep extension logging prefixed and easy to disable in production.

Comments

Markdown supported