Error sending message: Could not establish connection. Receiving end does not exist

Folder structure of my project

Background.ts

chrome.action.onClicked.addListener((tab) => {
  if (tab.id) {
    chrome.scripting.executeScript({
      target: { tabId: tab.id },
      files: ["content/content.js"],
    });
  }
});

content.ts

console.log("βœ… Content script loaded");

chrome.runtime.onMessage.addListener((message, _, sendResponse) => {
  console.log("πŸ“© Received message:", message);

  if (message.action === "toggle-dark-mode") {
    const isDarkMode = document.documentElement.classList.contains("dark-mode");

    if (isDarkMode) {
      document.documentElement.classList.remove("dark-mode");
      document.body.style.backgroundColor = "white";
      document.body.style.color = "black";
    } else {
      document.documentElement.classList.add("dark-mode");
      document.body.style.backgroundColor = "black";
      document.body.style.color = "white";
    }

    sendResponse({ darkMode: !isDarkMode });
  }
});

popup.tsx

import { useEffect, useState } from "react";

const Popup = () => {
  const [isDarkMode, setIsDarkMode] = useState(false);

  // Fetch dark mode state from storage when popup loads
  useEffect(() => {
    chrome.storage.sync.get("darkMode", (data) => {
      setIsDarkMode(data.darkMode ?? false);
    });
  }, []);

  // Toggle dark mode when button is clicked
  const toggleDarkMode = () => {
    chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
      if (!tabs[0]?.id) {
        console.error("❌ No active tab found.");
        alert("Error: No active tab found.");
        return;
      }
  
      chrome.tabs.sendMessage(
        tabs[0].id,
        { action: "toggle-dark-mode" },
        (response) => {
          if (chrome.runtime.lastError) {
            console.error("🚨 Error sending message:", chrome.runtime.lastError.message);
            alert("Error: Content script may not be injected.");
          } else {
            console.log("βœ… Response from content script:", response);
          }
        }
      );
    });
  };
  
  
  

  return (
    <div className="w-48 p-4 flex flex-col items-center bg-white shadow-lg rounded-lg">
      <h2 className="text-lg font-semibold mb-2">Dark Mode</h2>
      <button
        className={`px-4 py-2 rounded-md text-white ${
          isDarkMode ? "bg-gray-800" : "bg-blue-500"
        }`}
        onClick={toggleDarkMode}
      >
        {isDarkMode ? "Disable Dark Mode" : "Enable Dark Mode"}
      </button>
    </div>
  );
};

export default Popup;

manifest.json

{
  "manifest_version": 3,
  "name": "Dark Mode Toggle",
  "version": "1.0",
  "description": "Toggle dark mode on any website",
  "permissions": ["storage", "scripting", "activeTab"],
  "host_permissions": ["<all_urls>"],
  "action": {
    "default_popup": "index.html"
  },
  "background": {
    "service_worker": "src/background/background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["src/content/content.js"]
    }
  ]
}

vite.config.ts

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { crx } from "@crxjs/vite-plugin";
import manifest from "./src/manifest.json";
import path from 'path'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react(), crx({manifest})],
  build: {
    rollupOptions: {
      input: {
        background: "src/background/background.ts",
        content: "src/content/content.ts",
      },
    },
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
})

when i load the chrome extension and click on enable dark mode button then i get error. Everything i am doing correct and folder structure is also correct but I don’t know why always i am getting error that scrip is not injecting in the page

Hello, is this part of the FCC curriculum. I take it you are trying trying to implement dark mode, is this correct or are you developing a chrome extension?

I would suggest you post a repo with your code.

In Background.ts shouldn’t it be src/content/content.js?

Does it work if you reload the tab?

i am just learning to build a chrome extension with react + vite

1 Like

i am using typescript that is why i used ts in place of js
well i tried with js as well but then also it was not working

I meant in your files array. You have files: ["content/content.js"]

chrome.action.onClicked.addListener((tab) => {
  if (tab.id) {
    chrome.scripting.executeScript({
      target: { tabId: tab.id },
      files: ["content/content.js"],
    });
  }
});

Is that file not inside a src folder? So it should be src/content/content.js