Cómo Utilizar los Menús Contextuales en Extensiones de Chrome
Jul 21, 2024
Updated: Jun 24, 2026

Cómo Utilizar los Menús Contextuales en Extensiones de Chrome

En este post, exploraremos cómo podemos agregar funcionalidades a los menús contextuales (los menús que aparecen al hacer clic derecho) en Chrome usando las APIs disponibles. Esta guía es útil para quienes desarrollan extensiones y buscan mejorar la interacción con sus usuarios.

Recuerda que esta es una serie de posts sobre extensiones de Chrome. Si vienes desde el principio, en el capítulo 2 configuramos el manifest.json con Manifest V3 y el service worker de fondo, conceptos que usaremos aquí.

¿Qué son los Menús Contextuales?

Los menús contextuales en Chrome son aquellos que aparecen al hacer clic derecho sobre una página web. Chrome permite a quienes desarrollan extensiones agregar opciones personalizadas a estos menús, ofreciendo una mejor experiencia de usuario.

Configuración Inicial

Para empezar a trabajar con los menús contextuales, primero necesitamos otorgar los permisos necesarios en el archivo manifest.json de nuestra extensión:

{
  "permissions": ["contextMenus", "scripting"],
  "host_permissions": ["<all_urls>"]
}

Añadimos también el permiso scripting y host_permissions porque más adelante mostraremos el resultado directamente en la página con chrome.scripting.executeScript.

Nota sobre el ciclo de vida. En Manifest V3 el script de fondo (background.js) es un service worker no persistente: Chrome lo detiene y lo vuelve a crear cuando lo necesita. Por eso la creación de menús no debe hacerse en el nivel superior del archivo, porque podría perderse al reiniciarse el worker. La forma correcta es crear los menús dentro del evento chrome.runtime.onInstalled, que se ejecuta una sola vez cuando se instala o actualiza la extensión.

Creación de un Menú Contextual

Vamos a crear un menú contextual básico que aparecerá en cualquier parte de la página web. Como explicamos arriba, registramos toda la creación de menús dentro de chrome.runtime.onInstalled en nuestro background.js:

// background.js
chrome.runtime.onInstalled.addListener(() => {
  // Menú principal
  chrome.contextMenus.create({
    id: "myContextMenu",
    title: "Mi Menú Contextual",
    contexts: ["all"],
  });

  // Submenús: se anidan en el menú principal usando parentId
  chrome.contextMenus.create({
    id: "subMenu1",
    parentId: "myContextMenu",
    title: "Submenú 1",
    contexts: ["all"],
  });

  chrome.contextMenus.create({
    id: "subMenu2",
    parentId: "myContextMenu",
    title: "Submenú 2",
    contexts: ["all"],
  });

  // Opción que solo aparece cuando hay texto seleccionado
  chrome.contextMenus.create({
    id: "wordCount",
    title: "Contar Palabras",
    contexts: ["selection"],
  });
});

Como ves, cada menú se define con un id único, un title y la lista de contexts en los que debe mostrarse. Los submenús usan parentId para colgar del menú principal, y la opción wordCount usa el contexto selection para aparecer únicamente cuando el usuario ha seleccionado texto.

Gestión de Eventos de Clic

Para manejar las acciones cuando el usuario selecciona una opción del menú, registramos un único listener de chrome.contextMenus.onClicked y decidimos qué hacer con un switch sobre info.menuItemId. Tener un solo listener es importante en un service worker: evita registrar varios manejadores que se ejecutarían en cada clic y mantiene la lógica en un solo lugar.

// background.js (continuación)
chrome.contextMenus.onClicked.addListener((info, tab) => {
  switch (info.menuItemId) {
    case "subMenu1":
      console.log("Submenú 1 seleccionado");
      break;

    case "subMenu2":
      console.log("Submenú 2 seleccionado");
      break;

    case "wordCount":
      if (info.selectionText) {
        const wordCount = info.selectionText.trim().split(/\s+/).length;
        showWordCount(tab.id, wordCount);
      }
      break;
  }
});

Ejemplo de Uso: Contar Palabras Seleccionadas

Supongamos que queremos contar las palabras que el usuario ha seleccionado. Ya creamos la opción wordCount y la conectamos en el switch de arriba; ahora falta mostrar el resultado.

Aquí hay un detalle importante. En Manifest V3 el código de fondo corre en un service worker, que no tiene acceso al DOM, así que `alert()` no está disponible y lanzaría un error. En lugar de eso, inyectamos un pequeño script en la pestaña activa con chrome.scripting.executeScript para mostrar el conteo en la propia página:

// background.js (continuación)
function showWordCount(tabId, count) {
  chrome.scripting.executeScript({
    target: { tabId },
    // El argumento se pasa al script inyectado a través de "args"
    args: [count],
    func: (wordCount) => {
      // Este código sí corre en la página, donde el DOM existe
      window.alert(`Número de palabras: ${wordCount}`);
    },
  });
}

Tip. Si prefieres no interrumpir al usuario con una ventana, otras alternativas correctas para un service worker son enviar un mensaje a un content script con chrome.tabs.sendMessage o mostrar una notificación del sistema con chrome.notifications. Lo importante es no usar APIs del DOM directamente desde el service worker.

Eliminación y Actualización de Menús Contextuales

Además de crear menús contextuales, también podemos eliminarlos o actualizarlos según sea necesario.

Para eliminar un menú contextual, usamos chrome.contextMenus.remove:

chrome.contextMenus.remove("subMenu2", () => {
  console.log("Submenú 2 eliminado");
});

Para actualizar un menú contextual, usamos chrome.contextMenus.update:

chrome.contextMenus.update("myContextMenu", {
  title: "Mi Menú Contextual Actualizado",
});

Estas operaciones puedes ejecutarlas dentro de tus propios listeners (por ejemplo, en respuesta a otro clic o a un mensaje), no es necesario que vivan dentro de onInstalled.

Conclusión

Los menús contextuales son una herramienta poderosa para mejorar la interactividad de tus extensiones de Chrome. Con la API chrome.contextMenus puedes personalizar estos menús para ofrecer funcionalidades específicas que mejoren la experiencia del usuario. La clave bajo Manifest V3 es respetar el ciclo de vida del service worker: crea los menús en onInstalled, usa un solo listener de onClicked y muestra resultados en la página con chrome.scripting, no con APIs del DOM.

Ejercicios propuestos

  1. Crea una extensión con un menú contextual que solo aparezca sobre imágenes (contexto image) y que registre en consola la URL de la imagen al hacer clic.
  2. Amplía el ejemplo de "Contar Palabras" para que, además del total, muestre cuántos caracteres tiene la selección. Pásalos como argumentos al script inyectado.
  3. Sustituye el window.alert inyectado por una notificación del sistema con chrome.notifications. Compara las dos experiencias de usuario.

Resumen en 3 puntos

  1. En Manifest V3 los menús se crean dentro de chrome.runtime.onInstalled porque el service worker de fondo no es persistente.
  2. Maneja todos los clics con un único listener de chrome.contextMenus.onClicked y un switch (info.menuItemId) para mantener la lógica ordenada.
  3. El service worker no tiene DOM, así que en vez de alert() muestra resultados en la página con chrome.scripting.executeScript, un mensaje a un content script o chrome.notifications.

Eso es todo, espero que este post te haya sido útil para entender cómo trabajar con menús contextuales en Chrome y que lo puedas aplicar a alguna extensión que tengas en mente.

Déjame un comentario si te sirvió, si quieres añadir alguna opinión o si tienes alguna duda. Y recuerda que si te gustó, también puedes compartirlo usando los links a las redes sociales aquí abajo. ¡Hasta la próxima!

Sebastian Gomez

Sebastian Gomez

Creador de contenido principalmente acerca de tecnología.

Leave a Reply

0 Comments

Advertisements

Related Posts

Categorias