🧡

GEO con SvelteKit: Guía completa de implementación

intermediate

SvelteKit implementa GEO con svelte:head para meta tags y JSON-LD, y SSR activado por defecto. Los meta tags se colocan directamente en el componente de página usando svelte:head. El JSON-LD requiere la directiva @html para renderizar el bloque script correctamente en el HTML servido.

GEO con SvelteKit: Guía completa de implementación

SvelteKit implementa GEO con svelte:head para meta tags y JSON-LD, y SSR activado por defecto. Los meta tags se colocan directamente en el componente de página usando svelte:head. El JSON-LD requiere la directiva @html para renderizar el bloque script correctamente en el HTML servido.

SvelteKit usa SSR por defecto, lo que lo hace nativo para GEO: los crawlers de IA reciben HTML completo sin necesidad de ejecutar JavaScript.

Implementación de página

<!-- src/routes/guia-geo/+page.svelte -->
<script lang="ts">
  const publishedTime = '2026-04-18T00:00:00Z'
  const url = 'https://misitio.com/guia-geo'
  const description = 'GEO en SvelteKit con svelte:head, Open Graph y JSON-LD. Ejemplos completos.'

  const schema = JSON.stringify({
    '@context': 'https://schema.org',
    '@type': 'Article',
    headline: 'Cómo implementar GEO en SvelteKit',
    description,
    author: { '@type': 'Organization', name: 'Mi Empresa' },
    publisher: {
      '@type': 'Organization',
      name: 'Mi Sitio',
      logo: { '@type': 'ImageObject', url: 'https://misitio.com/logo.png' },
    },
    datePublished: publishedTime,
    dateModified: publishedTime,
    mainEntityOfPage: { '@type': 'WebPage', '@id': url },
  })
</script>

<svelte:head>
  <title>Cómo implementar GEO en SvelteKit | Mi Sitio</title>
  <meta name="description" content={description}>
  <meta name="author" content="Mi Empresa">
  <link rel="canonical" href={url}>

  <meta property="og:type" content="article">
  <meta property="og:title" content="Cómo implementar GEO en SvelteKit">
  <meta property="og:description" content={description}>
  <meta property="og:url" content={url}>
  <meta property="og:site_name" content="Mi Sitio">
  <meta property="og:image" content="https://misitio.com/og/guia-geo.jpg">
  <meta property="og:locale" content="es_ES">

  <meta property="article:published_time" content={publishedTime}>
  <meta property="article:modified_time" content={publishedTime}>
  <meta property="article:author" content="https://misitio.com/author/mi-empresa">
  <meta property="article:section" content="Guías técnicas">
  <meta property="article:tag" content="GEO">

  <meta name="robots" content="index, follow">

  <!-- eslint-disable-next-line svelte/no-at-html-tags -->
  {@html `<script type="application/ld+json">${schema}</script>`}
</svelte:head>

<main>
  <article>
    <h1>Cómo implementar GEO en SvelteKit</h1>
    <p>GEO en SvelteKit usa svelte:head para meta tags y JSON-LD. SSR activo por defecto.</p>
  </article>
</main>

Layout base con meta tags compartidos

Para compartir meta tags entre páginas, usa el layout raíz:

<!-- src/routes/+layout.svelte -->
<script lang="ts">
  import type { LayoutData } from './$types'
  export let data: LayoutData
</script>

<svelte:head>
  <meta name="robots" content="index, follow">
  <!-- Meta tags globales aquí -->
</svelte:head>

<slot />

Metadata dinámica con page.ts

Para páginas dinámicas, carga los datos en +page.ts y pásalos al componente:

// src/routes/blog/[slug]/+page.ts
import type { PageLoad } from './$types'

export const load: PageLoad = async ({ params, fetch }) => {
  const post = await fetch(`/api/posts/${params.slug}`).then(r => r.json())
  return { post }
}
<!-- src/routes/blog/[slug]/+page.svelte -->
<script lang="ts">
  import type { PageData } from './$types'
  export let data: PageData

  $: post = data.post
  $: schema = JSON.stringify({
    '@context': 'https://schema.org',
    '@type': 'Article',
    headline: post.title,
    description: post.excerpt,
    datePublished: post.publishedAt,
    dateModified: post.updatedAt,
    author: { '@type': 'Person', name: post.author },
    publisher: { '@type': 'Organization', name: 'Mi Sitio' },
  })
</script>

<svelte:head>
  <title>{post.title} | Mi Sitio</title>
  <meta name="description" content={post.excerpt}>
  <meta property="og:type" content="article">
  <meta property="article:published_time" content={post.publishedAt}>
  <meta property="article:modified_time" content={post.updatedAt}>
  {@html `<script type="application/ld+json">${schema}</script>`}
</svelte:head>

robots.txt

Crea static/robots.txt:

User-agent: GPTBot
Allow: /

User-agent: OAI-SearchBot
Allow: /

User-agent: ClaudeBot
Allow: /

User-agent: Claude-User
Allow: /

User-agent: Claude-SearchBot
Allow: /

User-agent: PerplexityBot
Allow: /

User-agent: Google-Extended
Allow: /

User-agent: BingBot
Allow: /

User-agent: *
Allow: /

Sitemap: https://misitio.com/sitemap.xml
Sitemap: https://misitio.com/llms.txt

Checklist GEO para SvelteKit

  • SSR activo (default en SvelteKit — verificar que prerender no está forzado a false)
  • svelte:head en cada página: title, description, canonical
  • svelte:head: Open Graph completo con og:type=article
  • svelte:head: article:published_time y article:modified_time
  • svelte:head: JSON-LD Article schema via @html
  • static/robots.txt con los 8 crawlers de IA permitidos
  • static/llms.txt con descripción del sitio y páginas principales
  • Sitemap con lastmod (plugin @sveltejs/adapter-static o manual)
  • Estructura de contenido en pirámide invertida
  • Core Web Vitals: LCP < 2.5s, INP < 200ms, CLS < 0.1