Claude Skills Guide

Building a Chrome Extension for Hashtag Generation on Social Media

Creating a Chrome extension that generates hashtags for social media platforms requires understanding browser extension architecture, content script injection, and the APIs available on platforms like X (Twitter), Instagram, and LinkedIn. This guide walks through the technical implementation for developers building these tools.

Extension Architecture Overview

A hashtag generator extension typically consists of three main components: a background service worker, content scripts that run on social media pages, and a popup interface for user configuration.

The manifest file defines the extension’s capabilities:

{
  "manifest_version": 3,
  "name": "Hashtag Generator",
  "version": "1.0.0",
  "permissions": ["activeTab", "storage"],
  "host_permissions": [
    "https://*.twitter.com/*",
    "https://*.instagram.com/*",
    "https://*.linkedin.com/*"
  ],
  "content_scripts": [{
    "matches": [
      "https://*.twitter.com/*",
      "https://*.instagram.com/*",
      "https://*.linkedin.com/*"
    ],
    "js": ["content.js"]
  }],
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon.png"
  }
}

The host permissions array is critical. Each social media platform requires explicit access grants in the manifest to allow your content script to read and manipulate the page.

Detecting Post Input Fields

Different platforms use different DOM structures for their post/composition boxes. Your content script needs to identify where the user types their content.

For X (Twitter), the compose box typically appears in the main timeline or on profile pages:

// content.js - Detect Twitter compose box
function findTwitterComposeBox() {
  // Twitter uses ARIA labels and role attributes
  const selectors = [
    '[aria-label="Tweet text"]',
    '[data-testid="tweetTextInput"]',
    '.public-DraftEditor-content'
  ];
  
  for (const selector of selectors) {
    const element = document.querySelector(selector);
    if (element) return element;
  }
  return null;
}

Instagram’s input field is nested within the create post modal:

// content.js - Detect Instagram input
function findInstagramInput() {
  const textarea = document.querySelector('textarea[aria-label*="Write"]');
  if (textarea) return textarea;
  
  // Alternative: look for the caption area in create modal
  const captionArea = document.querySelector('[contenteditable="true"][role="textbox"]');
  return captionArea;
}

The detection logic should handle dynamic page loads since social media platforms are single-page applications that update the DOM without full page refreshes.

Generating Hashtags

The core functionality involves analyzing the user’s post content and suggesting relevant hashtags. You can implement several strategies:

Keyword Extraction

Extract meaningful keywords from the post text:

function extractKeywords(text) {
  // Remove common stop words
  const stopWords = new Set([
    'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for'
  ]);
  
  // Clean and tokenize
  const words = text.toLowerCase()
    .replace(/[^\w\s]/g, '')
    .split(/\s+/)
    .filter(word => word.length > 2 && !stopWords.has(word));
  
  // Return unique words, preserving original order
  return [...new Set(words)];
}

Hashtag Database Strategy

For more sophisticated suggestions, maintain a local database of hashtag categories:

const hashtagDatabase = {
  'programming': ['#coding', '#developer', '#programming', '#tech', '#softwareengineering'],
  'javascript': ['#javascript', '#js', '#webdev', '#frontend', '#react'],
  'chrome-extension': ['#ChromeExtension', '#BrowserExtension', '#WebDevelopment'],
  'social-media': ['#SocialMedia', '#Marketing', '#DigitalMarketing', '#ContentStrategy']
};

function matchHashtags(keywords) {
  const suggestions = new Set();
  
  for (const keyword of keywords) {
    // Simple substring matching against database keys
    for (const [category, tags] of Object.entries(hashtagDatabase)) {
      if (category.includes(keyword) || keyword.includes(category)) {
        tags.forEach(tag => suggestions.add(tag));
      }
    }
  }
  
  return Array.from(suggestions).slice(0, 30); // Limit to 30 hashtags
}

Injecting Suggestions into the UI

Once you have hashtags, you need to display them to the user. The approach varies by platform:

function displayHashtagSuggestions(hashtags, container) {
  // Create a suggestions panel
  const panel = document.createElement('div');
  panel.className = 'hashtag-suggestions-panel';
  panel.style.cssText = 'padding: 12px; background: #f5f8fa; border-radius: 8px; margin-top: 8px;';
  
  const header = document.createElement('div');
  header.textContent = 'Suggested Hashtags';
  header.style.cssText = 'font-weight: 600; margin-bottom: 8px; color: #0f1419;';
  panel.appendChild(header);
  
  const tagContainer = document.createElement('div');
  tagContainer.style.cssText = 'display: flex; flex-wrap: wrap; gap: 6px;';
  
  hashtags.forEach(tag => {
    const tagElement = document.createElement('span');
    tagElement.textContent = tag;
    tagElement.style.cssText = 'background: #e8f5fd; color: #1d9bf0; padding: 4px 8px; border-radius: 4px; font-size: 12px; cursor: pointer;';
    tagElement.addEventListener('click', () => {
      copyToClipboard(tag);
    });
    tagContainer.appendChild(tagElement);
  });
  
  panel.appendChild(tagContainer);
  container.appendChild(panel);
}

Platform-Specific Considerations

Rate Limiting

Social media platforms enforce rate limits on their APIs. If your extension makes external API calls, implement exponential backoff:

async function fetchWithRetry(url, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      return await response.json();
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
      await new Promise(resolve => 
        setTimeout(resolve, Math.pow(2, attempt) * 1000)
      );
    }
  }
}

Content Security Policies

Modern social media platforms have strict Content Security Policies. Your extension cannot inject external scripts freely. Always use the extension’s content script context, which runs with elevated privileges but still must respect the page’s CSP for network requests.

Platform Changes

Social media platforms frequently update their DOM structures. Implement robust fallback detection:

function findInputField() {
  const strategies = [
    findTwitterComposeBox,
    findInstagramInput,
    findLinkedInComposeBox,
    findGenericTextArea
  ];
  
  for (const strategy of strategies) {
    const element = strategy();
    if (element) return element;
  }
  
  // Log for debugging when nothing works
  console.warn('Could not detect any known compose box');
  return null;
}

Storing User Preferences

Use the Chrome Storage API to persist user settings:

// Save user preferences
chrome.storage.local.set({
  maxHashtags: 30,
  preferredCategories: ['tech', 'development'],
  autoInsert: false
});

// Load on startup
chrome.storage.local.get(['maxHashtags', 'preferredCategories'], (result) => {
  console.log('Settings loaded:', result);
});

Testing Your Extension

Load your extension in Chrome by navigating to chrome://extensions/, enabling Developer Mode, and clicking “Load unpacked”. Test across different scenarios:

  1. Fresh install on a new social media page
  2. Navigating between different platform sections
  3. Posting with various content types
  4. Edge cases like empty posts or extremely long content

Summary

Building a hashtag generator Chrome extension requires handling dynamic DOM detection, implementing keyword extraction, managing platform-specific constraints, and providing a smooth user experience. The architecture outlined here gives you a solid foundation for creating a robust tool that works across multiple social media platforms.

The key challenges involve maintaining compatibility as platforms evolve, respecting their terms of service, and providing genuinely useful suggestions rather than generic hashtags. Focus on keyword relevance and you’ll create a tool that users find valuable.

Built by theluckystrike — More at zovo.one