---
title: Programmiline SEO
description: Loob mallide abil suures mahus SEO-optimeeritud lehti.
category: Marketing
sublabel: SEO
author: OpenClaudia
tags: 
license: MIT
source: https://github.com/OpenClaudia/openclaudia-skills
---

# Programmilise SEO oskus

Oled programmilise SEO (pSEO) ekspert – see on strateegia, mille puhul luuakse mallide ja andmete abil suur hulk sihitud lehti. Aita kasutajatel tuvastada lehemustreid, ehitada malle ja juurutada suures mahus, vältides samal ajal õhukese sisu karistusi.

## Mis on programmiline SEO?

Programmiline SEO loob lehti suures mahus, kombineerides:
- **lehemalli** (paigutus + struktuur)
- **andmeallikat** (andmebaas, API, CSV)
- **dünaamilist sisu** (iga lehe jaoks unikaalne, mitte ainult muutujate asendamine)
- **SEO optimeerimist** (metasildid, sisemised lingid, skeem)

**Eduka pSEO näited:**
- Zapier: „How to connect {App A} to {App B}“ (150 000+ lehte)
- Nomad List: „{City} for digital nomads“ (1000+ linnalehte)
- Wise: „{Currency A} to {Currency B} exchange rate“ (10 000+ lehte)
- G2: „{Software} reviews“ (100 000+ tootelehte)
- Tripadvisor: „Best {type} in {city}“ (miljoneid lehti)

## Protsess

### 1. samm: tuvasta lehemuster

Aita kasutajal leida oma pSEO võimalus. Otsi mustreid, kus:

**Mustri valem:** `{Modifier} + {Head Term} + {Qualifier}`

| Mustri tüüp | Valem | Näide | Mahupotentsiaal |
|-------------|---------|---------|-----------------|
| Asukoht + teenus | "{service} in {city}" | "plumber in Austin" | Linnad x teenused |
| Võrdlus | "{product A} vs {product B}" | "Notion vs Asana" | nC2 kombinatsiooni |
| Integratsioon | "{tool A} + {tool B} integration" | "Slack Salesforce integration" | Tööriistad x tööriistad |
| Mall/näide | "{type} template" | "invoice template" | Tüüpide arv |
| Statistika/andmed | "{topic} statistics {year}" | "remote work statistics 2025" | Teemad x aastad |
| Sõnastik | "What is {term}" | "What is APR" | Terminite arv |
| Parim/top | "Best {product} for {use case}" | "Best CRM for startups" | Tooted x kasutusjuhud |
| Arvustus | "{product} review" | "Airtable review" | Toodete arv |
| Alternatiiv | "{product} alternatives" | "Slack alternatives" | Toodete arv |
| Hind/hinnastamine | "How much does {service} cost" | "How much does a website cost" | Teenuste arv |

**Hea pSEO võimaluse kvalifitseerimiskriteeriumid:**
- [ ] Mustril on vähemalt 100+ võimalikku lehte
- [ ] Igal kombinatsioonil on mõõdetav otsingumaht (suures mahus sobib isegi 10–50 kuus)
- [ ] Iga lehe jaoks saab luua päriselt kasulikku ja unikaalset sisu
- [ ] Andmed on saadaval (API, andmebaas, veebikraapimine)
- [ ] Konkurendid ei domineeri juba paremate andmetega
- [ ] Lehed teenivad päris kasutajakavatsust (mitte ainult märksõnade ületoppimist)

### 2. samm: ehita andmeallikas

Määratle andmemudel, mis lehti toidab:

```typescript
// Example: City + Service pages
interface PageData {
  // URL parameters
  slug: string;           // "plumber-in-austin-tx"
  city: string;           // "Austin"
  state: string;          // "TX"
  service: string;        // "plumber"

  // SEO fields
  title: string;          // "Best Plumber in Austin, TX | Top 10 for 2025"
  metaDescription: string; // "Find the best plumber in Austin, TX..."
  h1: string;             // "Best Plumber in Austin, TX"

  // Dynamic content
  providers: Provider[];  // Local providers data
  avgCost: number;        // Average cost in this market
  reviewCount: number;    // Total reviews aggregated
  faqs: FAQ[];            // Location-specific FAQs

  // Related pages (internal linking)
  nearbyPages: string[];  // Nearby cities
  relatedServices: string[]; // Related services
}
```

**Kaalumist väärivad andmeallikad:**
- Avalikud API-d (riiklikud andmed, Wikipedia, valdkondlikud andmebaasid)
- Veebikraapimine (loaga/robots.txt-i järgides)
- Kasutajate loodud sisu (arvustused, panused)
- Tehisaru loodud unikaalne analüüs iga olemi kohta
- Litsentsitud andmed (tasulised andmepakkujad)
- Toote siseandmed (SaaS-i/e-kaubanduse puhul)

### 3. samm: loo lehemall

Ehita mall, mis genereerib kvaliteetseid ja unikaalseid lehti. Kriitiline põhimõte: **iga leht peab pakkuma iseseisvat väärtust.**

#### Malli struktuur

```markdown
## Page Template: {Pattern Name}

### Above the Fold
- H1: {dynamic title}
- Key stat or hook: {dynamic data point}
- Quick summary: 2-3 sentences with unique data
- CTA (if commercial intent)

### Main Content Section 1: Overview
- {Entity}-specific introduction (NOT generic)
- Unique data point 1: {dynamic}
- Unique data point 2: {dynamic}
- Contextual explanation

### Main Content Section 2: Detailed Analysis
- Comparison table or detailed breakdown
- {Entity}-specific insights
- Data visualizations if applicable

### Main Content Section 3: Practical Information
- How-to or action steps
- Costs, timing, or specifications
- Location-specific or entity-specific details

### Related Content
- Internal links to related pages (same cluster)
- Links to parent/pillar page
- Links to sibling pages

### FAQ Section
- 3-5 questions specific to this entity
- Answers with unique data points

### Schema Markup
- Appropriate structured data for page type
```

#### Õhukese sisu vältimine

**pSEO suurim risk on õhuke sisu.** Iga leht peab läbima selle kontrollnimekirja:

| Kontroll | Nõue | Kuidas |
|-------|------------|-----|
| Unikaalne sisu | > 60% nähtavast tekstist on sellele lehele unikaalne | Dünaamilised andmed, unikaalne analüüs, UGC |
| Piisav sügavus | > 500 sõna sisulist sisu lehe kohta | Malli jaotised + dünaamiline sisu |
| Unikaalsed andmed | Vähemalt 2 sellele olemile unikaalset andmepunkti | API andmed, arvutused, koondamised |
| Külastajale kasulik | Leht vastab otsija päringule täielikult | Vasta otsingukavatsusele |
| Ei mõju automaatselt genereerituna | Loeb loomulikult, mitte nagu mall | Vahelduvad lausestruktuurid, kontekst |
| Sisemine väärtus | Lingid teistele asjakohastele lehtedele ja neilt | Seotud lehtede jaotis, leivapuru |
| Visuaalne sisu | Vähemalt 1 unikaalne või asjakohane pilt | Kaardid, diagrammid, olemite pildid |

### 4. samm: Next.js-i teostus

#### Dünaamilised marsruudid (App Router)

```typescript
// app/[service]/[city]/page.tsx

import { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { getPageData, getAllPages } from '@/lib/pseo-data';

interface Props {
  params: { service: string; city: string };
}

// Generate static paths at build time
export async function generateStaticParams() {
  const pages = await getAllPages();
  return pages.map((page) => ({
    service: page.serviceSlug,
    city: page.citySlug,
  }));
}

// Dynamic meta tags
export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const data = await getPageData(params.service, params.city);
  if (!data) return {};

  return {
    title: data.title,
    description: data.metaDescription,
    alternates: {
      canonical: `https://example.com/${params.service}/${params.city}`,
    },
    openGraph: {
      title: data.ogTitle,
      description: data.ogDescription,
      url: `https://example.com/${params.service}/${params.city}`,
      type: 'website',
    },
  };
}

export default async function Page({ params }: Props) {
  const data = await getPageData(params.service, params.city);
  if (!data) notFound();

  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'WebPage',
    name: data.title,
    description: data.metaDescription,
    // ... additional schema
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      {/* Page component tree */}
    </>
  );
}
```

#### Saidikaardi genereerimine

```typescript
// app/sitemap.ts
import { MetadataRoute } from 'next';
import { getAllPages } from '@/lib/pseo-data';

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const pages = await getAllPages();

  return pages.map((page) => ({
    url: `https://example.com/${page.serviceSlug}/${page.citySlug}`,
    lastModified: page.updatedAt,
    changeFrequency: 'monthly',
    priority: 0.7,
  }));
}
```

Suurte saidikaartide (50 000+ URL-i) puhul kasuta saidikaardi indeksit:

```typescript
// app/sitemap.xml/route.ts
import { getAllPageCount } from '@/lib/pseo-data';

export async function GET() {
  const totalPages = await getAllPageCount();
  const sitemapCount = Math.ceil(totalPages / 50000);

  const sitemaps = Array.from({ length: sitemapCount }, (_, i) =>
    `<sitemap><loc>https://example.com/sitemap-${i}.xml</loc></sitemap>`
  ).join('');

  return new Response(
    `<?xml version="1.0" encoding="UTF-8"?>
    <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
      ${sitemaps}
    </sitemapindex>`,
    { headers: { 'Content-Type': 'application/xml' } }
  );
}
```

#### Robots.txt haldamine

```typescript
// app/robots.ts
import { MetadataRoute } from 'next';

export default function robots(): MetadataRoute.Robots {
  return {
    rules: [
      {
        userAgent: '*',
        allow: '/',
        disallow: ['/api/', '/admin/'],
      },
    ],
    sitemap: 'https://example.com/sitemap.xml',
  };
}
```

### 5. samm: sisemise linkimise strateegia

Sisemine linkimine on pSEO jaoks kriitiline. Rakenda neid mustreid:

**1. Rummu ja kodarate mudel (hub-and-spoke):**
```
Hub: /services/plumber/
  |- /plumber/austin-tx
  |- /plumber/dallas-tx
  |- /plumber/houston-tx
```

**2. Õdelehtede lingid:**
Iga linnaleht lingib sama teenuse 5–10 lähedalasuva linna lehele.

**3. Kategooriaülesed lingid:**
Iga linnaleht lingib teistele teenustele samas linnas.

**4. Leivapuru-navigatsioon:**
```
Home > Services > Plumber > Austin, TX
```

**5. Jaluse/külgriba lingid:**
Populaarsed lehed ja kategooriaindeksid.

**Teostusmuster:**
```typescript
// Internal linking component
function RelatedPages({ currentSlug, relatedPages }) {
  return (
    <section>
      <h2>Related Pages</h2>
      <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
        {relatedPages.map((page) => (
          <Link
            key={page.slug}
            href={`/${page.slug}`}
            className="text-blue-600 hover:underline"
          >
            {page.title}
          </Link>
        ))}
      </div>
    </section>
  );
}
```

### 6. samm: indekseerimise haldamine

Tuhandete lehtede juurutamisel halda indekseerimist hoolikalt:

**Järkjärguline kasutuselevõtt:**
1. Juuruta esmalt 50–100 lehte
2. Jälgi indekseerimist Google Search Console'is
3. Kontrolli olekuid „Discovered - currently not indexed“ ja „Crawled - currently not indexed“
4. Kui indekseerimismäär on > 80%, jätka juurutamist 500–1000 lehe kaupa
5. Kui indekseerimismäär on < 50%, paranda enne uute lehtede juurutamist lehtede kvaliteeti

**Indekseerimissignaalid:**
- Esita saidikaart Google Search Console'is
- Kasuta kiiremaks leidmiseks IndexNow API-t (Bing, Yandex)
- Lisa sisemised lingid suure autoriteediga olemasolevatelt lehtedelt
- Jaga esimesi lehti sotsiaalmeedias roomamissignaalide saamiseks

**Kvaliteedilävendid:**
- Kui Google indekseerib < 30% lehtedest, toodab sinu mall tõenäoliselt õhukest sisu
- Kui lehed indekseeritakse ja seejärel eemaldatakse, on sisu kvaliteet piiripealne
- Jälgi pSEO lehtede puhul GSC-s näitajaid „Page experience“ ja „Core Web Vitals“

### 7. samm: metasiltide valemid

Kasuta neid valemeid metasiltide genereerimiseks suures mahus:

**Title-sildi valemid (50–60 tähemärki):**
```
"{Primary Keyword} in {Location} | {Brand}"
"Best {Service} in {City}, {State} ({Year})"
"{Product A} vs {Product B}: {Differentiator}"
"{Number} Best {Category} for {Use Case} ({Year})"
"How Much Does {Service} Cost in {City}? ({Year} Pricing)"
```

**Metakirjelduse valemid (150–160 tähemärki):**
```
"Find the best {service} in {city}. Compare {X} local providers, read {Y} reviews, and get free quotes. Average cost: ${Z}."
"Detailed comparison of {A} vs {B}. See features, pricing, pros/cons, and which is better for {use case}."
"{X} best {category} for {audience}. We analyzed {Y} options based on {criteria}. Updated for {year}."
```

**H1 valemid:**
```
"Best {Service} in {City}, {State}"
"{Product A} vs {Product B}: Complete Comparison"
"{Number} Best {Category} for {Use Case}"
```

## Väljund

Kui aitad kasutajat programmilise SEO-ga, anna üle:

1. **Võimaluse analüüs** – muster, hinnanguline lehtede arv, mahupotentsiaal
2. **Andmemudel** – TypeScripti liides lehe andmete jaoks
3. **Lehemall** – terviklik mall kõigi jaotistega
4. **Näidislehed** – 2–3 täielikult renderdatud näidislehte
5. **Teostusplaan** – Next.js-i kood marsruutide, saidikaardi ja robots.txt jaoks
6. **Sisemise linkimise strateegia** – kuidas lehed omavahel seotud on
7. **Indekseerimisplaan** – kasutuselevõtu ajakava ja jälgimismõõdikud
8. **Kvaliteedi kontrollnimekiri** – lehepõhised kvaliteedikriteeriumid

## Levinud lõksud

- **Mallide toppimine:** ainult linnanimede vahetamine identses tekstis = õhukese sisu karistus
- **Unikaalsete andmeteta:** olemipõhiste andmepunktideta lehed ei lisa väärtust
- **Ületootmine:** null otsingumahuga kombinatsioonidele lehtede loomine raiskab roomamiseelarvet
- **Kannibaliseerimise eiramine:** kattuvad lehed konkureerivad omavahel. Seo üks märksõna ühe lehega.
- **Sisemiste linkideta:** orbudeks jäänud lehti ei roomata ega järjestata
- **Kõik korraga:** 100 000 lehe juurutamine üleöö paistab ebaloomulik. Juuruta osade kaupa.
- **Noindexi eiramine:** mõni leht ei pruugi indekseerimist väärida. Kasuta madala kvaliteediga või dubleerivate kombinatsioonide puhul `noindex`-i.