Etiqueta noscript en HTML: contenido cuando no hay scripts
La etiqueta <noscript> ofrece contenido alternativo cuando el scripting está deshabilitado o no disponible en el contexto del documento. Sirve, por ejemplo, para explicar cómo consultar unas lecciones cuando su filtro necesita JavaScript. Úsala para un aviso o una alternativa concreta, manteniendo el contenido principal disponible para todos.
Ejemplo mínimo de noscript
Coloca este fragmento dentro del <body> de un documento HTML:
<noscript>
<p>El filtro interactivo no está disponible. Puedes consultar la lista completa de lecciones.</p>
</noscript>
Al desactivar JavaScript y recargar el documento, aparece el párrafo. Con scripting habilitado no se muestra, aunque la página no incluya ningún <script>. El fragmento solo da un aviso: no crea la lista ni comprueba que exista un filtro.
Retira todo el elemento y desaparecerá la alternativa. Si retiras únicamente las etiquetas de apertura y cierre, conservando el párrafo, el aviso pasa a mostrarse siempre. Cambiar el texto modifica el mensaje, no la condición que lo activa.
Sintaxis y contexto válido
<noscript> tiene apertura y cierre obligatorios; no es un elemento vacío. Su análisis cambia con la ubicación y el estado de scripting, según el modelo de contenido del estándar:
- En el
<body>, con scripting deshabilitado, su modelo es transparente: el contenido debe ser válido en el contexto donde se coloca. Como hijo de<body>admite párrafos, listas y enlaces; dentro de un párrafo no permite introducir otro párrafo ni una lista. - En
<head>, solo puede contener<link>,<style>y<meta>. Un aviso con<p>o un enlace<a>corresponde al cuerpo. - Con scripting habilitado, el analizador HTML trata su contenido como texto, sin crear los elementos interiores habituales. Ese texto debe corresponder a HTML válido para el mismo contexto al interpretarse como alternativa.
No anides un <noscript> dentro de otro. Este mecanismo pertenece a la sintaxis HTML, habitualmente servida como text/html; no debe usarse en documentos XML/XHTML.
Por ejemplo, este fragmento se inserta dentro de un <head> existente. Añade un estilo para un párrafo con class="aviso" cuando los scripts están deshabilitados; no genera un mensaje por sí mismo:
<noscript>
<style>
.aviso { border-left: 3px solid #074f85; padding-left: 1rem; }
</style>
</noscript>
JavaScript desactivado frente a un script fallido
¿Aparece noscript si falla un script? No cuando el scripting sigue habilitado. Un archivo ausente, una excepción, un error de sintaxis o un bloqueo por la política de seguridad de contenido (CSP) pueden impedir ejecutar código sin activar la alternativa. <noscript> no supervisa esas incidencias.
Si el filtro no aparece, comprueba primero el estado de JavaScript y recarga. Después revisa en las herramientas del navegador la ruta y respuesta del archivo, los mensajes de Consola y los bloqueos de seguridad. Son diagnósticos distintos. Para conservar una página útil en todos esos casos, comienza con HTML funcional y añade las mejoras cuando el script se ejecute.
Caso práctico: lista disponible y filtro añadido por JavaScript
Guarda estos dos archivos juntos, en UTF-8, y abre lecciones.html en el navegador. El ejemplo funciona localmente: no necesita servidor, bibliotecas ni peticiones de datos.
Primero, lecciones.html contiene toda la lista:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Lecciones de HTML</title>
<style>
body {
max-width: 42rem;
margin: auto;
padding: 1rem;
font-family: system-ui, sans-serif;
line-height: 1.6;
color: #172b3a;
background: #fff;
}
label { display: block; }
input { box-sizing: border-box; max-width: 100%; font: inherit; }
:focus-visible { outline: 3px solid #074f85; outline-offset: 3px; }
</style>
<script src="filtro.js" defer></script>
</head>
<body>
<main>
<h1>Lecciones de HTML</h1>
<p>Consulta la lista completa; el filtro es una ayuda opcional.</p>
<noscript>
<p class="aviso">El filtro interactivo no está disponible. Todas las lecciones siguen en la lista.</p>
</noscript>
<ul id="lecciones">
<li>Párrafos y saltos de línea</li>
<li>Listas de ingredientes</li>
<li>Enlaces entre páginas</li>
</ul>
</main>
</body>
</html>
Después, filtro.js construye los controles, conecta el evento y los inserta antes de la lista:
{
const lista = document.getElementById("lecciones");
const elementos = [...lista.children];
const controles = document.createElement("div");
const etiqueta = document.createElement("label");
const entrada = document.createElement("input");
const estado = document.createElement("p");
etiqueta.htmlFor = "filtro-lecciones";
etiqueta.textContent = "Filtrar lecciones por texto";
entrada.id = "filtro-lecciones";
entrada.type = "search";
estado.setAttribute("aria-live", "polite");
function filtrar() {
const consulta = entrada.value.trim().toLocaleLowerCase("es");
let visibles = 0;
for (const elemento of elementos) {
const coincide = elemento.textContent.toLocaleLowerCase("es").includes(consulta);
elemento.hidden = !coincide;
if (coincide) visibles++;
}
estado.textContent = `${visibles} de ${elementos.length} lecciones visibles.`;
}
entrada.addEventListener("input", filtrar);
filtrar();
controles.append(etiqueta, entrada, estado);
lista.before(controles);
}
defer permite ejecutar el archivo después de analizar el HTML. El filtro compara texto sin distinguir mayúsculas; sí distingue acentos. hidden oculta las filas que no coinciden. El contador comunica el resultado también con texto y ofrece una actualización accesible mediante aria-live.
Prueba estas situaciones:
- JavaScript habilitado y archivo presente: aparecen el campo y «3 de 3 lecciones visibles». Usa Tab para llegar al campo, escribe
listasy comprueba que queda una lección. Escribezzzzpara obtener cero; borra la consulta para recuperar todas. - JavaScript desactivado: recarga. No existe el campo, se muestra el aviso de
<noscript>y permanecen las tres lecciones. - JavaScript habilitado y archivo ausente: renombra temporalmente
filtro.js, recarga y revisa el fallo de carga en las herramientas del navegador. No aparecen el filtro ni el aviso, pero la lista completa sigue disponible. Restaura el nombre al terminar. - Retirada de noscript: elimina el elemento completo. La lista y el filtro mantienen su comportamiento; solo desaparece el aviso sin scripts.
Esta mejora progresiva evita reservar la información esencial a <noscript>. La lista inicial sirve también cuando el JS falla. Los identificadores corresponden a este documento independiente; si reutilizas varias copias en una página, ajusta identificadores y selectores para evitar colisiones.
Atributos, accesibilidad y errores frecuentes
<noscript> no tiene atributos específicos. Los globales, como id, class y lang, identifican el elemento, permiten aplicar estilos o indican el idioma. Ninguno detecta fallos de descarga ni excepciones. src y defer pertenecen a <script>; display es una propiedad CSS y hidden en el código es una propiedad DOM de cada <li>.
Conserva etiquetas nativas dentro de la alternativa y ofrece una acción o información útil. Un mensaje que solo dice «activa JavaScript» deja sin resolver la necesidad del lector. No ocultes toda la página con CSS para forzar ese aviso ni añadas un rol ARIA a <noscript>: no lo necesita ni admite role, según la referencia técnica de MDN. El anuncio de sus descendientes depende de la tecnología de asistencia; no garantiza una alerta automática.
¿Dónde puede ponerse? En el cuerpo respetando el contenido permitido por su contexto, o en la cabecera con los metadatos indicados. No uses un párrafo de aviso dentro de <head> ni anides alternativas.
<script> incorpora el código; <noscript> proporciona la alternativa bajo otra condición. <search> puede delimitar una zona de búsqueda o filtrado, pero no ejecuta un filtro ni detecta errores. Para contenido desplegable que funcione sin scripts, <details> ofrece interacción nativa. Elige cada elemento por su función.
Compatibilidad y fuentes
Fuentes revisadas el 5 de octubre de 2026. <noscript> está disponible en los motores actuales de Chrome, Firefox y Safari, según los datos de compatibilidad incluidos en el HTML Living Standard. Ese soporte no implica que detecte errores de un archivo JS.
El estándar define el estado de scripting y las restricciones de análisis; MDN: <noscript> complementa atributos y comportamiento. Al verificarlo, desactiva JavaScript para el documento y recarga: retirar un <script> es una prueba diferente.