.htaccess y caché: activar gzip y Brotli, la caché del navegador y bloquear bots de IA en Apache
Publicado el 07-10-20268 min de lecturaPor la redacción de SmoothSeen
En el .htaccess de Apache, la compresión se activa con AddOutputFilterByType para Brotli y gzip, solo en tipos de texto. La caché del navegador se fija con mod_expires por tipo de fichero y con un Cache-Control de un año e immutable solo para ficheros con huella en el nombre. Los bots de IA de entrenamiento se vetan con mod_rewrite y un 403, sin tocar a los de búsqueda.
Lo esencial
- Con mod_brotli y mod_deflate, un HTML de 6.143 bytes viajó en 301 bytes con Brotli y en 414 con gzip en nuestra prueba con Apache httpd 2.4.69.
- Las imágenes WebP, JPEG o AVIF ya van comprimidas; meterlas en la lista de compresión gasta CPU sin ahorrar bytes.
- Un año de caché con immutable solo es seguro para ficheros con huella en el nombre; el HTML debe llevar no-cache para que se revalide en cada visita.
- Vetar GPTBot, ClaudeBot o CCBot es una decisión editorial que no te saca de ChatGPT ni de Claude; vetar OAI-SearchBot, Claude-SearchBot o PerplexityBot, sí.
- Un veto por user-agent no para a quien lo falsifica, y Google-Extended y Applebot-Extended solo se controlan en robots.txt.
Para comprobarlo en tu web: Auditoría SEO
En esta página
Apache decide tres cosas de esta guía: si un fichero viaja comprimido, cuánto tiempo puede guardarlo el navegador y a quién responde con un 403. No decide lo que haga un CDN que tengas delante, ni puede distinguir a un bot que se hace pasar por otro. Los fragmentos se han probado el 07-10-2026 con Apache httpd 2.4.69 en su imagen oficial de Docker (httpd:2.4), con curl desde otro contenedor. La redirección a HTTPS y las cabeceras de seguridad están en la guía de .htaccess para HTTPS, HSTS y cabeceras.
¿Qué módulos necesitas y cómo sabes si están?
- Módulo
- mod_deflate
- Para qué
- Compresión gzip
- Nota
- Envía
Vary: Accept-Encodingpor su cuenta1
- Módulo
- mod_brotli
- Para qué
- Compresión Brotli
- Nota
- Disponible desde Apache 2.4.262
- Módulo
- mod_filter
- Para qué
- La directiva
AddOutputFilterByType - Nota
- Cargado en el
httpd.confde serie
- Módulo
- mod_expires
- Para qué
Expiresy elmax-agedeCache-Controlpor tipo- Nota
- Se puede usar en .htaccess3
- Módulo
- mod_headers
- Para qué
- Cualquier otra cabecera, como
immutable - Nota
- Módulo
- mod_rewrite
- Para qué
- El veto por user-agent
- Nota
La imagen oficial trae los seis compilados, pero el httpd.conf de serie deja comentados mod_deflate, mod_brotli, mod_expires y mod_rewrite. En un hosting compartido no puedes verlo directamente: pregunta a soporte o haz la prueba del final. Si el módulo no está cargado, la directiva da un error 500, y eso es bueno: te enteras. Por eso este .htaccess no usa <IfModule>, que escondería el fallo.
Un recordatorio de la documentación de Apache: si tienes acceso a la configuración principal, pon esto en el VirtualHost, porque el .htaccess se lee en cada petición4.
Paso 1: compresión Brotli y gzip
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml
AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xmlEn la prueba, Apache respondió con Brotli cuando la petición aceptaba br y gzip, con gzip cuando solo aceptaba gzip, y sin comprimir cuando no pedía compresión. Estos son los bytes transferidos:
- Fichero
- HTML (
index.html) - Sin comprimir
- 6.143
- gzip
- 414
- Brotli
- 301
- Fichero
- CSS
- Sin comprimir
- 4.710
- gzip
- 286
- Brotli
- 156
- Fichero
- JavaScript
- Sin comprimir
- 5.670
- gzip
- 302
- Brotli
- 192
- Fichero
- Imagen WebP
- Sin comprimir
- 4.000
- gzip
- 4.000
- Brotli
- 4.000
Los ficheros de prueba son muy repetitivos y comprimen más que una web real; lo que importa es el orden de magnitud y que Brotli quedó por debajo de gzip en los tres textos.
Tres detalles que conviene saber:
text/javascriptyapplication/javascript, los dos. Elmime.typesde Apache 2.4.69 sirve los.jscomotext/javascript; muchos ejemplos antiguos solo listanapplication/javascripty el JavaScript sale sin comprimir.- Las imágenes, fuera. WebP, JPEG, PNG y AVIF ya van comprimidos. La documentación de mod_deflate las excluye en sus ejemplos1. SVG sí es texto y sí se comprime.
- BREACH. Las documentaciones de los dos módulos avisan de que algunas aplicaciones web son vulnerables a una fuga de información cuando una conexión TLS transporta datos comprimidos, y remiten a la familia de ataques BREACH12. Si tu web maneja tokens o datos personales en páginas dinámicas, revísalo antes de activarla en ellas.
Paso 2: caché del navegador sin servir versiones viejas
La regla de web.dev es sencilla: las URL con versión o huella en el nombre pueden guardarse un año (max-age=31536000), y las URL sin versión, como el HTML, deben llevar no-cache, que no significa «no guardes» sino «revalida antes de usar»5. MDN añade que immutable indica que la respuesta no cambiará mientras esté fresca, pensado justo para ese patrón de ficheros con huella6.
ExpiresActive On
ExpiresByType text/css "access plus 1 week"
ExpiresByType text/javascript "access plus 1 week"
ExpiresByType image/webp "access plus 1 month"
ExpiresByType image/avif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType font/woff2 "access plus 1 year"
# El HTML se guarda, pero se revalida en cada visita
Header set Cache-Control "no-cache" "expr=%{CONTENT_TYPE} =~ m#^text/html#"
# Ficheros con huella en el nombre (app.3f9a1c2b.js): un año e immutable
<FilesMatch "\.[0-9a-f]{8,}\.(css|js|mjs|woff2|webp|avif|png|jpe?g|svg)$">
Header set Cache-Control "max-age=31536000, immutable"
</FilesMatch>Las cabeceras que devolvió Apache 2.4.69:
- Petición
/(HTML)- Cache-Control obtenido
no-cache
- Petición
/assets/estilos.css- Cache-Control obtenido
max-age=604800
- Petición
/assets/app.3f9a1c2b.js- Cache-Control obtenido
max-age=31536000, immutable
- Petición
/assets/foto.webp- Cache-Control obtenido
max-age=2592000
Dos decisiones de este bloque:
- El HTML se reconoce por su tipo, no por la extensión. La condición
expr=sobre el tipo de contenido cubre cualquier respuesta HTML, termine o no su fichero en.html. Si tu CMS ya envía su propioCache-Control, comprueba concurlcuál sale al final. - El JavaScript con huella también recibe un
Expiresde una semana de mod_expires. No pasa nada: cuando una respuesta traemax-age, la norma HTTP obliga a ignorarExpires7.
El error que más cuesta ver: poner immutable a estilos.css sin huella. Si mañana cambias ese fichero, quien ya lo tenga en caché seguirá con la versión vieja hasta un año. Si tu CMS no añade huellas a los nombres, quédate con una semana.
Paso 3: bots de IA, separando búsqueda y entrenamiento
No todos los bots de IA hacen lo mismo, y vetar al equivocado tiene consecuencias distintas:
- Bot
- OAI-SearchBot
- Empresa
- OpenAI
- Para qué lo usa su dueño
- Mostrar webs en la búsqueda de ChatGPT
- Si lo vetas
- No apareces en las respuestas de búsqueda de ChatGPT8
- Bot
- GPTBot
- Empresa
- OpenAI
- Para qué lo usa su dueño
- Entrenar modelos
- Si lo vetas
- Tu contenido no se usa para entrenar; sigues pudiendo salir en ChatGPT8
- Bot
- Claude-SearchBot y Claude-User
- Empresa
- Anthropic
- Para qué lo usa su dueño
- Búsqueda y consultas de usuarios de Claude
- Si lo vetas
- Puede reducir tu visibilidad en Claude9
- Bot
- ClaudeBot
- Empresa
- Anthropic
- Para qué lo usa su dueño
- Entrenar modelos
- Si lo vetas
- Se excluye tu contenido futuro del entrenamiento9
- Bot
- PerplexityBot
- Empresa
- Perplexity
- Para qué lo usa su dueño
- Enlazar webs en sus resultados; no entrena modelos
- Si lo vetas
- Tus páginas pueden dejar de aparecer enlazadas en sus resultados10
- Bot
- CCBot
- Empresa
- Common Crawl
- Para qué lo usa su dueño
- Archivo abierto de la web
- Si lo vetas
- Sales de ese archivo11
El veto que probamos deja fuera a tres rastreadores de entrenamiento (GPTBot, ClaudeBot, meta-externalagent) y al de Common Crawl, y deja siempre abierto robots.txt:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/robots\.txt$
RewriteCond %{HTTP_USER_AGENT} (GPTBot|ClaudeBot|CCBot|meta-externalagent) [NC]
RewriteRule ^ - [F]Con user-agent como los que envían estos bots, los cuatro vetados recibieron 403 en /blog/ y 200 en /robots.txt. OAI-SearchBot, ChatGPT-User, Claude-SearchBot, PerplexityBot, Googlebot y un Chrome normal recibieron 200 en las dos. La excepción de robots.txt no es un adorno: Anthropic explica que bloquear a sus bots por IP les impide leer tu robots.txt y que eso puede no garantizar la exclusión9.
Antes de usarlo, cuatro límites:
- El user-agent se puede falsificar. Common Crawl dice que conoce rastreadores que se hacen pasar por CCBot y recomienda comprobar los rangos de IP que publica11. OpenAI y Perplexity también publican los suyos810.
- Google-Extended y Applebot-Extended no son user-agents. Google-Extended es solo una marca de robots.txt, no afecta a la Búsqueda de Google y no tiene user-agent propio12. Applebot-Extended no rastrea páginas13. Una regla en el .htaccess no los ve: se controlan en robots.txt.
- ChatGPT-User y Perplexity-User pueden no seguir robots.txt, según sus dueños, porque actúan cuando un usuario lo pide810. Si los vetas en el servidor, desapareces de esas consultas.
- Un 403 no se ve en robots.txt. Si otro miembro del equipo revisa solo robots.txt, no sabrá que existe el veto. Documéntalo.
Para los bots que respetan robots.txt, robots.txt es la vía más limpia: está documentada por cada empresa y cualquiera puede leerla. El veto del .htaccess queda como refuerzo:
User-agent: GPTBot
User-agent: ClaudeBot
User-agent: CCBot
User-agent: meta-externalagent
User-agent: Google-Extended
User-agent: Applebot-Extended
Disallow: /
User-agent: *
Allow: /Cómo comprobarlo
- Compresión.
curl -sI -H "Accept-Encoding: br, gzip" https://www.example.com/tiene que mostrarContent-Encoding: br; con"Accept-Encoding: gzip",Content-Encoding: gzip. En el panel Red de las herramientas del navegador también lo ves. - Caché.
curl -sIsobre la portada, un CSS y un fichero con huella: compara cadaCache-Controlcon la tabla del paso 2. - Bots.
curl -sI -A "GPTBot/1.4" https://www.example.com/debe dar 403;curl -sI -A "OAI-SearchBot/1.4" https://www.example.com/, 200; y/robots.txtcon el user-agent vetado, 200. - Después de cada cambio, pide una página.
httpd -tno lee los .htaccess: un error solo aparece como 500 al pedir la página.
Qué hace SmoothSeen con esto
SmoothSeen comprueba si tu web sirve el texto comprimido con gzip o Brotli dentro de Posicionamiento web. En Posicionamiento IA lee tu robots.txt separando los rastreadores de búsqueda de los de entrenamiento, sin contar como fallo vetar a los de entrenamiento, y pide la página con el user-agent de cada rastreador de IA, de un navegador y de Googlebot para detectar si el servidor o el cortafuegos responde 403 a alguno.
Qué hacer esta semana
Pide tu portada con curl -sI -H "Accept-Encoding: br, gzip" y con -A "OAI-SearchBot/1.4". Si no sale comprimida, o si el rastreador de búsqueda de ChatGPT recibe un 403 que nadie decidió, empieza por ahí. Para comprobar a la vez la compresión, robots.txt y los vetos del servidor, analiza tu web con SmoothSeen.
Preguntas frecuentes
¿Brotli o gzip: cuál activo?
Los dos. El navegador anuncia en cada petición qué algoritmos acepta; con los dos filtros activos, en nuestra prueba Apache usó Brotli cuando se aceptaba y gzip cuando no. Así, Brotli sirve a los navegadores modernos y gzip queda para los demás. Brotli dejó el HTML en 301 bytes frente a 414 con gzip. Si tu hosting no tiene mod_brotli, gzip solo ya es una mejora grande.
¿Por qué mis cambios de CSS no se ven después de activar la caché?
Porque el navegador sigue usando la copia guardada mientras no caduque. Es lo que pasa si das una caché larga, o immutable, a un fichero cuyo nombre no cambia cuando cambia su contenido. La solución es añadir una huella o un número de versión al nombre en cada publicación, o bajar la duración de esos ficheros a una semana.
¿Bloquear GPTBot me saca de ChatGPT?
No. OpenAI explica que GPTBot se usa para entrenar modelos y que la búsqueda de ChatGPT depende de OAI-SearchBot, con ajustes independientes para cada uno. Puedes vetar el entrenamiento y seguir saliendo en las respuestas con búsqueda. Lo que sí te saca es vetar a OAI-SearchBot, en robots.txt o con un 403 en el servidor.
¿Es mejor bloquear bots en robots.txt o en .htaccess?
Para los que respetan robots.txt, robots.txt: es la vía que documentan sus dueños, se ve desde fuera y no rompe nada si te equivocas de nombre. El .htaccess sirve para reforzarlo o para bots que no lo respetan, pero solo frena a quien se identifica con honradez y es invisible para quien revise robots.txt.
Fuentes
- 1Apache Module mod_deflate, Apache Software Foundation, consultada el 07-10-2026.
- 2Apache Module mod_brotli, Apache Software Foundation, consultada el 07-10-2026.
- 3Apache Module mod_expires, Apache Software Foundation, consultada el 07-10-2026.
- 4Apache HTTP Server Tutorial: .htaccess files, Apache Software Foundation, consultada el 07-10-2026.
- 5Prevent unnecessary network requests with the HTTP Cache, web.dev (Google), consultada el 07-10-2026.
- 6Cache-Control, MDN Web Docs, actualizada el 17-09-2026.
- 7RFC 9111: HTTP Caching, sección 5.3 (Expires), IETF, junio de 2022.
- 8Overview of OpenAI Crawlers, OpenAI, consultada el 07-10-2026.
- 9Does Anthropic crawl data from the web, and how can site owners block the crawler?, Anthropic, actualizada el 07-04-2026.
- 10Perplexity Crawlers, Perplexity, consultada el 07-10-2026.
- 11CCBot, Common Crawl, consultada el 07-10-2026.
- 12Google's common crawlers: Google-Extended, Google Search Central, actualizada el 14-07-2026.
- 13About Applebot, Apple, publicada el 04-09-2026.
Cómo citar este artículo
SmoothSeen. (2026, 7 de octubre). .htaccess y caché: activar gzip y Brotli, la caché del navegador y bloquear bots de IA en Apache. https://smoothseen.com/es/blog/apache-htaccess-compresion-cache-bots/
Sigue leyendo
Posicionamiento web (SEO): qué es, cómo funciona y cómo mejorarlo en 2026
Qué es el posicionamiento web, cómo decide Google qué páginas muestra y una checklist priorizada para mejorarlo con herramientas gratuitas.
.htaccess y HTTPS: redirigir http a https, activar HSTS y cabeceras de seguridad en Apache
Cómo redirigir http a https en .htaccess o en el VirtualHost de Apache, activar HSTS sin riesgos y añadir cabeceras de seguridad. Configuración probada.
Accesibilidad web y SEO: qué pide WCAG 2.2, qué coincide con Google y qué exige la ley europea
Qué es la accesibilidad web, qué pide WCAG 2.2 (alt, contraste, nombres accesibles, idioma, zoom), qué tiene que ver con el SEO y a quién obliga la ley europea.