JavaScript SEO

Mi az a JavaScript SEO?

Googlebot JavaScript rendering folyamat: HTML azonnali indexelés vs JS Crawl → Render Queue → Render → Index késleltetéssel

A JavaScript SEO a JavaScript-alapú weboldalak keresőmotor optimalizálása. Modern web framework-ök (React, Vue, Angular, Svelte) gyakran client-side rendering (CSR) megoldást használnak, amely azt jelenti, hogy a tartalom JavaScript-tel generálódik a böngészőben, nem pedig a szerverről érkezik kész HTML-ként.

Probléma:

A keresőmotoroknak (különösen a Google-nek) renderelniük kell a JavaScript-et, hogy lássák a tartalmat. Ez:

  • Lassabb indexelés (napokkal késleltetett renderelés)
  • ⚠️ Hiányos indexelés (nem minden JavaScript fut le)
  • 🐌 Lassú oldalbetöltés (több lépés szükséges)

Megoldás:

JavaScript SEO technikák:

  1. Server-Side Rendering (SSR) - Szerver rendereli a HTML-t
  2. Static Site Generation (SSG) - Build-időben generált HTML
  3. Hybrid Rendering - SSR + CSR kombinációja
  4. Prerendering - Kritikus oldalak előre renderelése
  5. Progressive Enhancement - Alapvető tartalom HTML-ben, JavaScript csak kiegészítés

Google és a JavaScript: Hogyan működik?

Google Crawlolási és Indexelési Folyamat

Hagyományos HTML oldal (nincs JavaScript):

1. Googlebot letölti a HTML-t
   ↓
2. Azonnal látja a tartalmat
   ↓
3. Indexeli (percek/órák)

JavaScript-alapú oldal (CSR):

1. Googlebot letölti a HTML-t (üres vagy skeleton)
   ↓
2. Bekerül a renderelési queue-ba
   ↓ (KÉSLELTETÉS: órák/napok)
3. JavaScript renderelés (WRS - Web Rendering Service)
   ↓
4. Tartalom látható
   ↓
5. Indexelés

Késleltetés oka:

A Google a JavaScript renderelést külön queue-ban végzi (Web Rendering Service), mivel ez erőforrás-igényes. Ez azt jelenti:

  • Első crawl: HTML letöltés (üres tartalom)
  • Késleltetés: órák, napok, akár hetek
  • Második fázis: JavaScript renderelés
  • Csak ezután: Indexelés

⚠️ KRITIKUS: Ha fontos tartalom csak JavaScript-tel jelenik meg → lassú vagy hiányos indexelés!

Google JavaScript Renderelés Limitációi

Mit tud a Google:

✅ Modern JavaScript renderelés (Chrome 91+ alapú WRS)
✅ ES6+ szintaxis
✅ Fetch API, async/await
✅ React, Vue, Angular framework-ök

Mire vigyázz:

⚠️ Késleltetett renderelés - Nem azonnal történik
⚠️ Timeout limitek - Max ~5 másodperc futási idő
⚠️ Memória limitek - Nagy JavaScript fájlok problémásak
⚠️ External API-k - Lehet, hogy nem futnak le rendereléskor

Rendering Stratégiák

SSR vs CSR vs SSG renderelési stratégiák összehasonlítása SEO szempontból

1. Client-Side Rendering (CSR)

Mi ez: A böngésző rendereli a JavaScript-et, a szerver üres HTML-t küld.

Hogyan működik:

Szerver → Üres HTML
        ↓
Böngésző letölti a JavaScript-et (bundle.js)
        ↓
JavaScript fut
        ↓
DOM frissül
        ↓
Tartalom látható

HTML példa (CSR):

<!DOCTYPE html>
<html>
<head>
  <title>My App</title>
</head>
<body>
  <div id="root"></div> <!-- Üres! -->
  <script src="/bundle.js"></script>
</body>
</html>

React példa (CSR):

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

Előnyök:

✅ Egyszerű fejlesztés
✅ Gazdag interaktivitás
✅ Gyors navigáció SPA-ban (oldaltöltés után)

Hátrányok:

❌ Lassú első betöltés (FCP, LCP)
❌ SEO problémák (késleltetett indexelés)
❌ Nem működik JavaScript nélkül
❌ Nagy bundle size (100-500KB+)

SEO hatás:

  • ⚠️ Google renderelni fogja, de napokkal később
  • ❌ Meta tag-ek (title, description) nem látszanak azonnal
  • ❌ Social share-ek (Facebook, Twitter) nem működnek

Mikor használd:

  • Admin panel, dashboard (nem kell SEO)
  • Belső alkalmazások
  • HA SSR/SSG nem opció

2. Server-Side Rendering (SSR)

Mi ez: A szerver rendereli a HTML-t minden kérésnél, kész tartalommal.

Hogyan működik:

Felhasználó kérés
        ↓
Szerver rendereli a React/Vue/Angular-t
        ↓
Kész HTML küldetik
        ↓
Böngésző azonnal látja a tartalmat
        ↓
JavaScript letöltődik (hydration)
        ↓
Interaktív lesz

Next.js példa (SSR):

// pages/blog/[slug].js
export async function getServerSideProps(context) {
  const { slug } = context.params;
  const post = await fetchPost(slug);
  
  return {
    props: { post }
  };
}

export default function BlogPost({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

HTML kimenet (SSR):

<!DOCTYPE html>
<html>
<head>
  <title>Blog Post Title</title>
  <meta name="description" content="Blog post description">
</head>
<body>
  <div id="root">
    <div>
      <h1>Blog Post Title</h1>
      <p>This is the actual content, visible immediately!</p>
    </div>
  </div>
  <script src="/bundle.js"></script>
</body>
</html>

Előnyök:

SEO-barát - Google azonnal látja a tartalmat
✅ Gyors első betöltés (FCP)
✅ Social share működik
✅ Működik JavaScript nélkül (progresszív fejlesztés)

Hátrányok:

❌ Lassabb szerver válaszidő (minden kérés renderelés)
❌ Bonyolultabb deployment (Node.js szerver szükséges)
❌ Magasabb szerver költség (CPU/RAM igény)

Framework-ök SSR-rel:

  • Next.js (React) - getServerSideProps
  • Nuxt.js (Vue) - asyncData, fetch
  • Angular Universal (Angular)
  • SvelteKit (Svelte)

Mikor használd:

  • E-commerce (termék oldalak)
  • Blogok, híroldalak
  • Landing page-ek
  • Bármi, ahol SEO fontos

3. Static Site Generation (SSG)

Mi ez: A HTML build-időben generálódik, nem futásidőben.

Hogyan működik:

Build idő:
  ↓
Framework rendereli az összes oldalt
  ↓
Statikus HTML fájlok generálódnak
  ↓
Deployment (CDN-re)
  ↓
Felhasználó kérés
  ↓
Statikus HTML szolgálva (villámgyors!)

Next.js példa (SSG):

// pages/blog/[slug].js
export async function getStaticPaths() {
  const posts = await fetchAllPosts();
  
  return {
    paths: posts.map(post => ({
      params: { slug: post.slug }
    })),
    fallback: false
  };
}

export async function getStaticProps({ params }) {
  const post = await fetchPost(params.slug);
  
  return {
    props: { post },
    revalidate: 3600 // ISR: újra-generálás 1 óránként
  };
}

export default function BlogPost({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

Build parancs:

npm run build
# → Generálja: out/blog/seo-tips.html, out/blog/react-guide.html, stb.

Előnyök:

Leggyorsabb - Statikus HTML, CDN-ről szolgálva
SEO-barát - Kész HTML, nincs renderelés
Alacsony költség - Nincs szerver szükséges
Biztonságos - Nincs server-side kód futásidőben

Hátrányok:

❌ Build idő növekszik (1000+ oldalnál)
❌ Nem jó dinamikus tartalomhoz (felhasználói adatok, valós idejű)
❌ Frissítés = újra build szükséges

Framework-ök SSG-vel:

  • Next.js (React) - getStaticProps
  • Gatsby (React)
  • Nuxt.js (Vue) - nuxt generate
  • Eleventy (JavaScript)
  • Hugo (Go-based)

Mikor használd:

  • Blogok, dokumentációk
  • Landing page-ek, marketing oldalak
  • Portfolio oldalak
  • Bármi, ahol tartalom nem változik gyakran

4. Incremental Static Regeneration (ISR)

Mi ez: SSG + háttérben történő újra-generálás.

Hogyan működik:

Build idő: Statikus HTML-ek generálva
  ↓
Felhasználó kérés → Statikus HTML szolgálva
  ↓
Háttérben (revalidate idő után):
  ↓
Újra-generálás (frissített tartalom)
  ↓
Következő felhasználó → Új verzió

Next.js példa (ISR):

export async function getStaticProps() {
  const posts = await fetchPosts();
  
  return {
    props: { posts },
    revalidate: 60 // Újra-generálás 60 másodpercenként
  };
}

Előnyök:

✅ SSG gyorsasága
✅ Frissített tartalom (build nélkül)
✅ Skálázható nagy oldalaknál

Mikor használd:

  • E-commerce termékek (árak változnak)
  • Híroldalak (új cikkek)
  • Felhasználó-generált tartalom

5. Hybrid Rendering

Mi ez: SSR + CSR kombinációja.

Stratégia:

  • Első betöltés: SSR (gyors FCP, SEO)
  • Navigáció: CSR (gyors, SPA élmény)

Next.js példa:

// Oldal 1: SSR
export async function getServerSideProps() {
  return { props: { data } };
}

// Oldal 2: SSG
export async function getStaticProps() {
  return { props: { data }, revalidate: 3600 };
}

// Oldal 3: CSR (client-side fetch)
export default function Page() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetch('/api/data').then(res => res.json()).then(setData);
  }, []);
  
  return <div>{data}</div>;
}

Előny: Legjobb kompromisszum (sebesség + SEO + UX)

JavaScript SEO Best Practices

1. Meta tag-ek dinamikus frissítése

Probléma:

SPA-ban az URL változik, de a meta tag-ek nem frissülnek.

Megoldás:

React (react-helmet):

import { Helmet } from 'react-helmet';

function BlogPost({ post }) {
  return (
    <>
      <Helmet>
        <title>{post.title} - My Blog</title>
        <meta name="description" content={post.excerpt} />
        <meta property="og:title" content={post.title} />
        <meta property="og:image" content={post.image} />
        <link rel="canonical" href={`https://example.com/blog/${post.slug}`} />
      </Helmet>
      
      <article>
        <h1>{post.title}</h1>
        <p>{post.content}</p>
      </article>
    </>
  );
}

Vue (vue-meta):

export default {
  metaInfo() {
    return {
      title: this.post.title,
      meta: [
        { name: 'description', content: this.post.excerpt },
        { property: 'og:title', content: this.post.title }
      ],
      link: [
        { rel: 'canonical', href: `https://example.com/blog/${this.post.slug}` }
      ]
    };
  }
};

2. Lazy loading és code splitting

Probléma:

Egyetlen hatalmas bundle.js fájl (500KB+) → lassú betöltés.

Megoldás:

React lazy loading:

import React, { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Betöltés...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

Next.js dynamic import:

import dynamic from 'next/dynamic';

const DynamicComponent = dynamic(() => import('./Component'), {
  loading: () => <p>Betöltés...</p>,
  ssr: false // Ne renderelődjön server-side
});

Eredmény:

bundle.js: 100KB (kritikus kód)
chunk-1.js: 50KB (lazy loaded)
chunk-2.js: 80KB (lazy loaded)

→ Gyorsabb első betöltés (csak 100KB töltődik le először)

3. Linkelés és routing

Probléma:

SPA-ban a linkek gyakran JavaScript event handler-ekkel működnek:

<div onClick={() => navigate('/page')}>Link</div>

→ Google nem látja linkként!

Megoldás:

Használj valódi <a> tag-eket:

// ❌ Rossz
<div onClick={() => navigate('/page')}>Link</div>

// ✅ Jó
<a href="/page" onClick={(e) => {
  e.preventDefault();
  navigate('/page');
}}>Link</a>

// ✅ Vagy (React Router)
<Link to="/page">Link</Link>

// ✅ Vagy (Next.js)
<Link href="/page">Link</Link>

Miért fontos?

  • Google követi a <a> tag-eket (belső linkek)
  • JavaScript onClick nem mindig fut le crawloláskor

4. Structured data (Schema.org)

JSON-LD a head-ben:

// Next.js példa
export default function BlogPost({ post }) {
  const schema = {
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": post.title,
    "author": {
      "@type": "Person",
      "name": post.author
    },
    "datePublished": post.date,
    "image": post.image
  };
  
  return (
    <>
      <Head>
        <script
          type="application/ld+json"
          dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
        />
      </Head>
      <article>...</article>
    </>
  );
}

5. Infinite scroll és pagination SEO

Probléma:

Infinite scroll → nincs külön URL → Google nem látja a régebbi tartalmakat.

Megoldás A - Pagination URL-ek:

/blog/page/1/
/blog/page/2/
/blog/page/3/
<Link href="/blog/page/2">Következő oldal</Link>

Megoldás B - “Load More” gomb:

<button onClick={loadMore}>Több betöltése</button>

Megoldás C - View All link:

<a href="/blog/all">Összes cikk megtekintése</a>

6. Image lazy loading

Probléma:

Minden kép azonnal betöltődik → lassú oldalbetöltés.

Megoldás:

<img 
  src="/image.jpg" 
  alt="Description"
  loading="lazy" 
/>

Vagy React komponens:

import { LazyLoadImage } from 'react-lazy-load-image-component';

<LazyLoadImage
  src="/image.jpg"
  alt="Description"
  effect="blur"
/>

Framework-specifikus SEO tippek

React SEO (Next.js)

Next.js az ajánlott megoldás React SEO-hoz.

1. SSG használata bloghoz:

// pages/blog/[slug].js
export async function getStaticPaths() {
  const posts = await fetchPosts();
  return {
    paths: posts.map(post => ({ params: { slug: post.slug } })),
    fallback: 'blocking'
  };
}

export async function getStaticProps({ params }) {
  const post = await fetchPost(params.slug);
  return {
    props: { post },
    revalidate: 3600
  };
}

2. Dynamic sitemap:

// pages/sitemap.xml.js
function generateSiteMap(posts) {
  return `<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
      ${posts.map(post => `
        <url>
          <loc>https://example.com/blog/${post.slug}</loc>
          <lastmod>${post.date}</lastmod>
        </url>
      `).join('')}
    </urlset>`;
}

export async function getServerSideProps({ res }) {
  const posts = await fetchPosts();
  const sitemap = generateSiteMap(posts);
  
  res.setHeader('Content-Type', 'text/xml');
  res.write(sitemap);
  res.end();
  
  return { props: {} };
}

export default function Sitemap() {}

3. next-seo package:

import { NextSeo } from 'next-seo';

export default function Page() {
  return (
    <>
      <NextSeo
        title="Page Title"
        description="Page description"
        canonical="https://example.com/page"
        openGraph={{
          url: 'https://example.com/page',
          title: 'Page Title',
          description: 'Page description',
          images: [{ url: 'https://example.com/og-image.jpg' }]
        }}
      />
      <h1>Content</h1>
    </>
  );
}

Vue SEO (Nuxt.js)

Nuxt.js az ajánlott megoldás Vue SEO-hoz.

1. SSG használata:

// nuxt.config.js
export default {
  target: 'static',
  generate: {
    routes: async () => {
      const posts = await fetchPosts();
      return posts.map(post => `/blog/${post.slug}`);
    }
  }
};
npm run generate
# → Statikus HTML-ek generálva

2. Meta tag-ek:

export default {
  head() {
    return {
      title: this.post.title,
      meta: [
        { hid: 'description', name: 'description', content: this.post.excerpt },
        { hid: 'og:title', property: 'og:title', content: this.post.title }
      ]
    };
  }
};

3. Nuxt sitemap module:

// nuxt.config.js
export default {
  modules: ['@nuxtjs/sitemap'],
  sitemap: {
    hostname: 'https://example.com',
    gzip: true,
    routes: async () => {
      const posts = await fetchPosts();
      return posts.map(post => `/blog/${post.slug}`);
    }
  }
};

Angular SEO (Angular Universal)

Angular Universal az ajánlott megoldás Angular SEO-hoz.

1. Angular Universal telepítés:

ng add @nguniversal/express-engine

2. SSR használata:

npm run build:ssr
npm run serve:ssr

3. Meta tag-ek:

import { Meta, Title } from '@angular/platform-browser';

export class BlogPostComponent {
  constructor(
    private meta: Meta,
    private title: Title
  ) {}
  
  ngOnInit() {
    this.title.setTitle(this.post.title);
    this.meta.updateTag({ name: 'description', content: this.post.excerpt });
    this.meta.updateTag({ property: 'og:title', content: this.post.title });
  }
}

JavaScript SEO Ellenőrzés

1. Google Search Console URL vizsgálat

Lépések:

  1. Google Search Console
  2. URL vizsgálat
  3. Írd be az URL-t
  4. “Tesztelés élő URL-en”
  5. “Crawlolt oldal megtekintése” → Renderelt HTML

Mit nézz:

  • Látszik-e a tartalom?
  • Meta tag-ek rendben?
  • Linkek crawlolhatók?

2. JavaScript teszt (fetch as Google)

Chrome DevTools:

  1. Nyisd meg az oldalt
  2. F12 → Network tab
  3. Disable JavaScript (Ctrl+Shift+P → “Disable JavaScript”)
  4. Frissítsd az oldalt
  5. Látszik-e a tartalom?

Ha nem látszik: CSR van, SSR/SSG szükséges SEO-hoz.

3. Mobile-Friendly Test

URL: https://search.google.com/test/mobile-friendly

Ellenőrzi:

  • JavaScript renderelés
  • Mobilbarát-e
  • Látható tartalom

4. Lighthouse audit

npm install -g lighthouse

lighthouse https://example.com --view

Mit mér:

  • First Contentful Paint (FCP)
  • Largest Contentful Paint (LCP)
  • SEO score
  • JavaScript futási idő

Kapcsolódó Videók

Google Search Central: JavaScript SEO

Gyakran Ismételt Kérdések

Mi az a JavaScript SEO?

A JavaScript SEO a JavaScript-alapú weboldalak (React, Vue, Angular, stb.) keresőmotor optimalizálása. A fő kihívás, hogy a Google-nek renderelnie kell a JavaScript-et a tartalom megjelenítéséhez, ami késleltetést és potenciális indexelési problémákat okozhat. A JavaScript SEO technikák biztosítják, hogy a keresőmotorok megfelelően lássák és indexeljék a dinamikus tartalmat.

Látja-e a Google a JavaScript tartalmat?

Igen, a Google képes JavaScript renderelésre 2015 óta (WRS - Web Rendering Service). Azonban van késleltetés - a JavaScript renderelés napokkal később történhet, mint az első crawlolás. Ezért a kritikus tartalom (title, meta, fő szöveg) lehetőleg legyen elérhető JavaScript renderelés nélkül is, vagy használj server-side rendering (SSR) / static site generation (SSG) megoldást.

Mi a különbség a CSR, SSR és SSG között?

CSR (Client-Side Rendering): A böngésző rendereli a JavaScript-et, a HTML üres. Lassú első betöltés, SEO problémák. SSR (Server-Side Rendering): A szerver rendereli a HTML-t kéréskor, gyors első betöltés, SEO-barát. SSG (Static Site Generation): Build-időben generált statikus HTML, leggyorsabb, ideális blogokhoz. Hybrid: SSR + CSR kombináció (pl. Next.js).

Miért lassú a JavaScript SEO?

A JavaScript renderelés több lépést igényel: (1) HTML letöltése (üres), (2) JavaScript letöltése (100-500KB+), (3) JavaScript parseolás és futtatás, (4) Tartalom megjelenítése. Ez 2-5 másodperc lehet. A Google-nek külön renderelési queue-ba kell tennie az oldalt, ami napokkal késleltetheti az indexelést. SSR/SSG megoldással ez elkerülhető.

Melyik framework a legjobb SEO-hoz?

SSR/SSG támogatással minden framework jó lehet. Ajánlások: Next.js (React alapú, beépített SSR/SSG), Nuxt.js (Vue alapú, beépített SSR/SSG), Angular Universal (Angular SSR), SvelteKit (Svelte alapú), Gatsby (React SSG). A csupán CSR-es framework-ök (Create React App, Vue CLI default) nem ajánlottak SEO-hoz megfelelő konfigurálás nélkül.

Kell-e külön SEO a Single Page Application-höz?

Igen, az SPA-k (Single Page Application) speciális SEO kihívásokat jelentenek: (1) URL változások nem okoznak valódi oldalbetöltést, (2) Meta tag-ek nem frissülnek automatikusan, (3) Google lassabban indexeli. Megoldások: Dynamic meta tag frissítés (react-helmet, vue-meta), Proper routing (history API), SSR/SSG implementálás, Prerendering kritikus oldalakhoz.

Következő lépések

Most, hogy megértetted a JavaScript SEO alapjait:

  • Válaszd ki a megfelelő rendering stratégiát (SSR/SSG/Hybrid)
  • Implementálj dinamikus meta tag-eket
  • Optimalizáld a bundle size-t (code splitting)
  • Teszteld az oldalt Google Search Console-ban
  • Ellenőrizd a Core Web Vitals-t
  • Olvasd el a Core Web Vitals útmutatót
  • Nézd meg a Mobile-First Indexing cikket

Források

Frissítve: