Busqué en Google el servicio que vendo, en mi ciudad, y no aparecía. El método completo que usé para arreglarlo, paso a paso y con los scripts.

Gratis, a cambio de saber quién eres
Te lo doy completo y sin costo. Solo te pido el correo para poder escribirte después y preguntarte cómo te fue: si algo no te sirvió, quiero saberlo. Nada de spam.
Un correo de confirmación y ya. Puedes salirte cuando quieras.
Una auditoría le puso 75 sobre 100 a mi propio sitio. Peor: busqué en Google el servicio exacto que vendo, en mi propia ciudad, y no aparecía. Ni en la primera página ni en la tercera.
Arreglé cada cosa, anoté lo que funcionó y lo que me costó tiempo, y lo empaqueté en este skill. Estos son los números finales, medidos en producción sobre este mismo sitio que estás leyendo:
Puedes abrir PageSpeed Insights, poner chiragx.com y comprobarlo ahora mismo. No te pido que me creas.

Es un skill de Claude Code. Descomprime la carpeta dentro de tus skills:
~/.claude/skills/web-playbook-100/
En Windows es C:\Users\TU-USUARIO\.claude\skills\. Se activa solo cuando le pidas auditar o mejorar el SEO de un sitio.
¿No usas Claude Code? Igual te sirve. Todo es Markdown y los scripts corren solos desde la terminal. Abre SKILL.md y léelo como el manual que es.
El skill se activa cuando le hablas de SEO, PageSpeed, Core Web Vitals, fuentes, imágenes o de "por qué no aparezco en Google". Para no depender de eso, nómbralo: usa el skill web-playbook-100. Y dale estas cuatro cosas en la primera frase, porque sin ellas tiene que preguntar:
/es/, /en/).Un cambio, una medición. Pide siempre el antes y el después con el mismo comando, y que te diga qué no pudo verificar. El prompt con el que arranco cualquier sitio:
Usa el skill web-playbook-100. Mi sitio es https://midominio.com, rutas /es/ y /en/, alojado en [Cloudflare / WordPress / ...]. Corre scripts/audit.sh con --sitemap y dame las brechas ordenadas por impacto según el skill, con el comando con el que comprobaste cada una. No cambies nada todavía.
En cada paso te dejo el prompt exacto, lo que Claude hace solo y lo que sigue siendo tuyo. Al final está la lista completa de lo que nadie puede hacer por ti.
Casi todo el mundo se salta este paso y por eso arregla lo que no era. Antes de tocar una línea:
Apunta los cuatro resultados en un archivo. Al final vas a volver a medir con lo mismo, y ahí es donde ves si sirvió.
El script scripts/audit.sh del skill hace la parte técnica de esto por ti: con --sitemap revisa códigos de respuesta, redirecciones, canonicals, hreflang y metadatos de todas las URLs de tu sitemap de un tirón, y además comprueba que obligas HTTPS, qué cabeceras mandas y qué dice tu robots.txt de cada rastreador de IA. Y scripts/psi.js corre PageSpeed tres veces, saca la mediana y te lista lo que se pide antes del LCP.

Pídeselo así:
Mide https://midominio.com/es/ con scripts/psi.js tres veces en móvil (PSI_KEY está en el entorno), corre los bloques 1 a 3 de scripts/browser-audit.js en la página y guarda todo en medicion-inicial.md. No cambies nada.
Lo que hace solo: PageSpeed con mediana, la lista de lo que se carga antes del LCP, CLS y LCP en navegador real y la batería de curl. Lo que te toca a ti: sacar la clave gratuita de la API de PageSpeed (cinco minutos, con tu cuenta de Google), abrir el sitio en tu teléfono con datos, buscar tu servicio más tu ciudad en incógnito desde tu ciudad, y contar tus servicios.
Este fue el cambio que más movió la aguja, y no tiene nada de técnico.
Si vendes cinco servicios y los tienes como cinco párrafos dentro del home, Google tiene una página para posicionar en cinco búsquedas distintas. Va a perder las cinco. Cada servicio necesita su propia URL, con su propio título, su propia descripción y su propio contenido de verdad.
En mi caso pasé de un home con una sección de servicios a doce páginas (seis servicios en dos idiomas), cada una con:
Service y FAQPage.El skill trae esto en references/arquitectura.md, con el criterio para decidir qué merece página propia y qué no. Regla corta: si alguien podría buscarlo por su nombre, merece página.
Pídeselo así:
Estos son mis servicios: [lista]. Con references/arquitectura.md dime cuáles merecen URL propia, propón slug en español e inglés, título de hasta 60 caracteres y descripción de hasta 158 para cada uno, y la estructura de secciones. Redacta solo cuando te dé precios, preguntas reales de clientes y casos.
Lo que hace solo: decidir qué merece página, proponer slugs, metadatos y estructura, redactar, y enlazar los silos en las dos direcciones si tiene tu código. Lo que te toca a ti: los hechos (precios, rangos, las preguntas que te hacen de verdad, casos con cifras), aprobar cada texto y, si usas un constructor visual, crear las páginas a mano.
Aquí es donde la mayoría de los sitios pierden puntos por cosas invisibles. El orden que funciona:
Person u Organization), qué vendes (Service), tus preguntas (FAQPage) y la ruta de navegación (BreadcrumbList). Valida cada página en la prueba de resultados enriquecidos.lastmod real. Un sitemap escrito a mano se queda viejo en dos semanas.Cuando esto esté listo, verifica el sitio en Google Search Console, sube el sitemap y pide la indexación de las páginas nuevas. También date de alta en Bing Webmaster Tools: es media hora y es de donde sale buena parte de lo que responden los buscadores con IA.
Search Console tiene su curva y hay decisiones que dependen de cómo esté armado tu sitio. Lo dejo mencionado como paso porque explicarlo bien es una conversación, no un párrafo. Escríbeme y lo vemos con tu caso en la mano.
Tener certificado no es lo mismo que obligar a usarlo. Puedes tener el candado y que http://tudominio.com siga sirviendo la página entera sin cifrar, con respuesta 200 y sin redirigir a ninguna parte. Pasa más de lo que crees, y lo compruebas en un segundo:
curl -sIL http://tudominio.com | grep -i "^HTTP/\|^location:"
Si en esa cadena no aparece un salto a https://, tienes tres problemas a la vez. Uno: el formulario de contacto de tu web viaja sin cifrar. Dos: los enlaces viejos que te apuntan a http://www. quedan contados como una URL distinta, así que la autoridad que te mandan se reparte en vez de sumarse. Y tres, el que nadie asocia: cada redirección extra cuesta tiempo de carga en móvil. En una medición real que hice, la cadena de saltos se estaba comiendo 0,61 segundos del renderizado.
En Cloudflare es un interruptor: SSL/TLS → Edge Certificates → Always Use HTTPS. Si no usas Cloudflare, es una regla de redirección 301 en tu servidor.
Ya que estás ahí, mira si mandas alguna cabecera de seguridad. Lo normal es que no mandes ninguna. Con un archivo _headers (o el equivalente de tu hosting) pones el mínimo sensato:
/* X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin X-Frame-Options: SAMEORIGIN
De HSTS te aviso: obliga al navegador a recordar durante meses que tu sitio solo va por HTTPS. Es bueno, pero si algo se te rompe no puedes deshacerlo rápido porque la orden ya está guardada en el navegador de cada visitante. Actívalo cuando el resto esté estable, no el primer día.
Pídeselo así:
Arregla canonical, hreflang recíproco con x-default, sitemap con lastmod real y los títulos y descripciones fuera de norma en [mi código / mi plantilla]. Genera el JSON-LD por plantilla y comprueba que parsea. Comprueba HTTPS forzado y cabeceras. Antes y después con scripts/audit.sh --sitemap.
Lo que hace solo: todo lo que vive en el código o la plantilla, y la comprobación desde fuera. Con un token de Cloudflare, también el interruptor de HTTPS y las cabeceras. Lo que te toca a ti: verificar el sitio en Search Console y en Bing Webmaster Tools, subir el sitemap, pedir la indexación URL por URL (Google da una cuota diaria pequeña), decidir HSTS y, sin token, tocar los interruptores de tu hosting.
Esta es la parte con más mito por metro cuadrado. Lo que sí funcionó, en orden de impacto:
Google Fonts te cuesta una conexión a otro dominio antes de poder pintar una letra. Bájalas y sírvelas tú. Dos avisos que me costaron tiempo:
font-display: optional en la fuente del cuerpo. Con swap el texto se repinta y ahí nace buena parte de tu salto de contenido. swap solo es aceptable si ya ajustaste el respaldo con métricas medidas (el bloque 5 de browser-audit.js las calcula): entonces el texto se repinta pero no se mueve.scripts/selfhost-fonts.js hace la bajada y la deduplicación solo.
<picture>, dejando el original como respaldo. Mi home pasó de 1.013 KB a 533 KB sin que se note diferencia a la vista.img{max-width:100%}, tiene que llevar height:auto. Sin eso las imágenes se aplastan. Este error estuvo semanas en mi sitio y lo vine a ver en una grabación de pantalla.Llegar a cero es cuestión de reservar espacio: dimensiones en imágenes, alturas en lo que carga después, y nada que se mueva cuando entra la fuente. El script scripts/browser-audit.js te mide el salto, el elemento más grande y el contraste real en un navegador de verdad, que es distinto de lo que reporta un laboratorio.
Convertir a AVIF no basta. Un archivo de 1000px de ancho metido en un hueco que mide 340px sigue mandando el triple de píxeles de los que se ven. PageSpeed lo reporta como Improve image delivery y te dice exactamente cuánto sobra.
La regla es simple: mira el ancho real en pantalla, multiplícalo por dos (por las pantallas de alta densidad) y genera esa variante. Hueco de 340px, archivo de 700px. En mi propio sitio eso era una sola imagen sobrando 23 KiB.
ffmpeg -i original.jpg -vf "scale=-2:868:flags=lanczos" -q:v 3 medio.jpg ffmpeg -i medio.jpg -c:v libaom-av1 -crf 34 -cpu-used 6 -still-picture 1 medio.avif
Y una que se paga cara: si cambias el contenido de una imagen, cámbiale el nombre. Las imágenes suelen servirse con caché de treinta días. Si reescribes el mismo archivo, todo el que ya lo había visto sigue viendo el viejo durante un mes, y tú lo das por corregido.
loading="lazy" solo existe para <img>. Cualquier background-image, inline o en CSS, se pide en cuanto el elemento existe, esté donde esté. En mi home eran veinte fondos de tarjetas (eventos, portadas, miniaturas de YouTube) a varias pantallas del pliegue: 642 KB de imágenes pedidas antes del LCP, compitiendo en un 4G lento con el texto del hero. Resultado: el párrafo principal tardaba 3,5 s en pintarse teniendo su HTML listo desde el medio segundo.
Lo primero que probé, content-visibility: auto en las secciones lejanas, no lo evita: Chrome deja de pintar la sección, pero sigue descargando sus fondos. Lo comprobé en el trace. Descártalo para esto.
Lo que sí funciona es no declarar el fondo hasta que hace falta: la declaración va en un atributo data-bg y un script de diez líneas la pasa a style cuando el elemento se acerca al viewport. Con un comprobador por scroll, como el de las animaciones de entrada, que no depende de que IntersectionObserver se ejecute:
<div class="event-img" data-bg="background-image:url('/images/evento.jpg')"></div>
(function(){var els=[].slice.call(document.querySelectorAll('[data-bg]'));var t=null;
function apply(el){el.style.cssText+=';'+el.getAttribute('data-bg');el.removeAttribute('data-bg');}
function check(){t=null;var h=window.innerHeight+600;
els=els.filter(function(el){var r=el.getBoundingClientRect();
if(r.bottom>-600&&r.top<h){apply(el);return false;}return true;});}
function onS(){if(!t)t=setTimeout(check,80);}
window.addEventListener('scroll',onS,{passive:true});window.addEventListener('resize',onS);
window.addEventListener('load',check);check();})();
Si las tarjetas las genera tu servidor, el cambio va en la plantilla y el script en el pie común, para que todas las páginas lo tengan. Con eso, lo que se pide antes del LCP bajó de 958 KB a 434 KB. En PageSpeed de Google: móvil de 88 a 91 con LCP de 3,5 s a 3,2 s y CLS 0; escritorio 99 con LCP 0,7 s. (En Lighthouse local da 95 y 2,4 s; la red que simula Google es más lenta, y ese es el número que cuenta.)
La forma de encontrar esto no es adivinar: en el JSON de Lighthouse, lista las peticiones cuyo inicio es anterior al LCP y ordénalas por peso. Ahí sale, en la primera pantalla, qué le está robando el ancho de banda al elemento que importa.
Si tu sitio tiene modo claro y oscuro tienes dos paletas, y la auditoría mide una sola: la que sirves por defecto. Un mismo color me daba 6,16 en oscuro y 4,47 en claro. El mínimo para texto pequeño es 4,5. Por tres centésimas sale marcado en rojo.
Revisa los dos temas antes de dar por buena la accesibilidad. En el navegador, forzando el esquema y midiendo el color calculado contra su fondo real.
Un aviso de método: no te fíes de un barrido automático propio. Si el texto va encima de una imagen o un degradado, calcular el contraste contra el color de fondo del contenedor da números inventados. A mí un script así me sacó treinta y un fallos, de los que uno era real. Para esto, la lista que te da Lighthouse es la fuente buena; tu script sirve para confirmarla, no para sustituirla.
Pídeselo así:
Fuentes: corre scripts/selfhost-fonts.js con mi URL de Google Fonts, sustituye las etiquetas externas por @font-face locales con rangos de peso y calcula los respaldos con el bloque 5 de browser-audit.js. Imágenes: scripts/to-avif.sh sobre /images, picture con respaldo, width y height, y data-bg para los fondos fuera del primer pliegue. Un cambio por despliegue, y CLS y LCP en navegador después de cada uno.
Lo que hace solo: fuentes, respaldos con métricas medidas, AVIF, dimensiones, fondos perezosos, contraste desde los tokens y la medición. Lo que te toca a ti: aprobar cada despliegue y mirar el sitio en tu teléfono después de cada uno, porque el número no ve si algo quedó feo. Y los ajustes del CDN si no diste token.
Esto es lo que casi nadie hace y es lo que separa "una web más" de "el referente del tema en tu país".
Google no solo indexa páginas, mantiene un grafo de entidades: personas, empresas, lugares y cómo se relacionan. Si tú no eres una entidad para Google, compites solo por palabras. Si lo eres, compites por ser quien eres.
Los pasos, en orden:
Person u Organization en tu sitio con un @id estable, y referencia ese mismo @id desde todas las páginas.sameAs a tus perfiles reales: LinkedIn, GitHub, YouTube, X, tu ficha de empresa.Lo de Wikidata tiene reglas de notabilidad y se puede borrar si lo haces mal, así que no lo tomes a la ligera. Está en references/entidad.md con el detalle, pero si vas a hacerlo para tu negocio, háblame antes y te digo si calificas y cómo plantearlo.

Pídeselo así:
Genera el bloque Person u Organization con @id estable y sameAs con estos perfiles: [lista]. Ponlo en todas las plantillas referenciado por @id. Redacta una descripción de hasta 150 caracteres que sirva igual en Instagram, X, LinkedIn, YouTube y Facebook. Busca fuentes independientes sobre mí y dime si califico para Wikidata y con qué referencias.
Lo que hace solo: el schema, la descripción y el borrador de la ficha con sus fuentes. Lo que te toca a ti: editar cada perfil social con tu sesión, crear el ítem de Wikidata con tu cuenta y responder si lo cuestionan, sugerir el cambio en el panel de Google y reclamar tu perfil de empresa.
Un sitio en 100 que no publica nada vuelve a bajar. Necesitas dos cosas.
Un lugar donde publicar sin tocar código. Yo monté un CMS propio sobre Cloudflare porque quería controlar el HTML que sale, pero cualquier cosa sirve mientras publiques de verdad. Lo importante es que subir un artículo te tome quince minutos, no una tarde: si te cuesta, no lo vas a hacer. El montaje está en references/stack.md y references/cms-y-contenido.md.
Saber de dónde viene la gente. Mide el primer contacto, no el último: si alguien te encontró por Google en marzo y te escribió por WhatsApp en mayo, eso fue Google, no WhatsApp. Guarda el origen en el navegador la primera vez y mándalo con el formulario. Sin esto vas a estar adivinando qué canal te trae clientes.
Pídeselo así:
Monta la captura de primer contacto (utm_source, utm_medium, utm_campaign, referrer, página de entrada y fecha) guardada en el navegador y enviada con el formulario. Genera mis enlaces con UTM para [canales]. Propón un calendario de artículos: dos de intención de compra por cada uno de coyuntura, con el título de búsqueda de cada uno.
Lo que hace solo: el código de atribución, los enlaces con UTM, el calendario y los borradores. Lo que te toca a ti: conectar el CRM o el correo donde caen los leads, usar los enlaces con UTM de verdad en cada canal, publicar con ritmo y aprobar cada artículo. La experiencia es tuya; nadie la inventa por ti.
Este es el paso que más gente se salta, y el único donde no puedes hacer trampa.
Te va a pasar esto: corres una auditoría, te dice que tienes cien y pico de enlaces entrantes de treinta dominios, y te sientes bien. Después miras la lista y te encuentras dominios como .sbs, .cfd, .icu, .party, .monster, con títulos tipo "seo domain research", "Domain Report" o "URL Shared", casi todos alojados en Finlandia o Francia.
Esos no son enlaces. Son basura automática. Se generan solas cada vez que alguien mete tu dominio en una herramienta de análisis: la herramienta publica una página con el resultado, y esa página te enlaza. Correr auditorías las fabrica. No te hacen daño, porque los buscadores las ignoran, pero tampoco te suman nada, y te dan una sensación falsa de que ya tienes enlaces.
Cómo distinguir uno bueno de uno malo, sin herramienta de pago:
Y ahora lo que sí funciona, en orden de facilidad:
http://www.midominio.com: sin cifrar, con www y con dos redirecciones antes de llegar. El enlace estaba, pero llegaba a una URL que no era la buena. Pedir que lo cambien a la versión correcta es un mensaje de dos líneas.Lo que no te recomiendo: comprar enlaces, intercambiarlos en masa, o pagar por "500 backlinks garantizados". Eso construye exactamente el perfil que acabo de describir como basura, y encima pagando.
Una nota de expectativas: esto es lento y no lo arregla una tarde. Es el único paso de esta guía que depende de otras personas, y por eso es el que más gente abandona.

Pídeselo así:
Aquí está la lista de backlinks de mi auditoría: [pegada o CSV]. Sepárala en reales y automáticos con los criterios del skill. Después corre scripts/enlaces.sh con mi dominio, mi marca y estas URLs donde aparezco: [lista]. Redacta el mensaje de dos líneas para cada corrección.
Lo que hace solo: separar la lista, comprobar cómo te enlaza cada página (sin cifrar, con www, con saltos, con nofollow) y quién te menciona sin enlazar, redactar los mensajes y corregir los enlaces en tus propias propiedades si tiene acceso. Lo que te toca a ti: enviar cada mensaje, pedir reciprocidad a tus socios y esperar. Es el único paso que depende de otras personas.
Cada vez más gente no busca: pregunta. A ChatGPT, a Claude, a Gemini, o al resumen que Google pone arriba. Si tu web está afinada para el buscador clásico pero los modelos no te pueden leer, desapareces de la mitad de las consultas sin enterarte.
La buena noticia es que casi todo el trabajo ya lo hiciste en los pasos 3 y 5. Falta poco:
curl -sL https://tudominio.com/ | grep "una frase de tu página". Si no aparece, para esos modelos tu página está en blanco.robots.txt. Si usas Cloudflare, mira si tienes activado el bloqueo automático de bots de IA: viene encendido en algunas cuentas y decide por ti.llms.txt en la raíz. Es un archivo de texto que le explica al modelo qué es tu sitio y cuáles son tus páginas importantes. El estándar es joven, cuesta veinte minutos y aún no hay motivo para no tenerlo.Person u Organization del paso 5. Para un modelo, ese bloque es la forma más limpia de saber quién eres sin adivinar.Esto es lo que en las auditorías empieza a aparecer como GEO (Generative Engine Optimization). Es lo bastante nuevo como para que casi nadie lo tenga, y por eso mismo es donde más barato sale destacar hoy.

Pídeselo así:
Comprueba que el contenido principal está en el HTML sin JavaScript en mis páginas principales, revisa robots.txt para GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot y Google-Extended, y redacta un llms.txt con mis páginas importantes. Dime qué tengo que apagar en Cloudflare.
Lo que hace solo: la comprobación, el robots.txt, el llms.txt y, con token, los dos controles de Cloudflare. Lo que te toca a ti: sin token, apagar el bloqueo de bots de IA en Security y el "Managed robots.txt" en AI Crawl Control. Y decidir si quieres que las IAs te lean. La respuesta suele ser sí.
El skill trae veinticuatro errores documentados en references/errores.md, cada uno con lo que costó. Estos seis son los que más veo:
curl, no mirando la barra del navegador.
Con el skill y un token bien acotado, Claude hace la mayor parte del trabajo y lo verifica. Esto no lo puede hacer nadie por ti, y es exactamente donde se atasca casi todo el mundo:
Vuelve a los cuatro números del paso 1 y compáralos. Llegaste cuando:
Si te sale todo menos aparecer en la búsqueda, lo que falta suele ser tiempo, entidad (paso 5) y enlaces (paso 7). Son los dos pasos lentos y los que más rinden.
Gratis, a cambio de saber quién eres
Te lo doy completo y sin costo. Solo te pido el correo para poder escribirte después y preguntarte cómo te fue: si algo no te sirvió, quiero saberlo. Nada de spam.
Un correo de confirmación y ya. Puedes salirte cuando quieras.
¿Te trabaste en algún paso?
El recurso te lleva de cero a cien solo, pero hay pasos que se explican mejor hablando. Si llegaste hasta ahí y algo no cuadra, mándame el enlace de tu sitio y te digo qué está pasando.
Agendar una llamada →