Przejdź do treści
Biblioteka skilli
Programowanie · Przegląd i audyt

nextjs-i18n-seo

/nextjs-i18n-seo

Audytuje i naprawia SEO wielojęzycznych stron w Next.js App Router: indeksowanie, przekierowania 307 zamieniane na 301, adresy lokalizacji, sitemap i hreflang.

Repozytorium
inkstone ↗
Licencja
MIT
Ostatnia zmiana repozytorium
27.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
6
Przestarzałość

Brak sygnałów. Repozytorium zmienione 27.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Audytuje i naprawia SEO wielojęzycznych stron w Next.js App Router: indeksowanie, przekierowania 307 zamieniane na 301, adresy lokalizacji, sitemap i hreflang.

Argumenty

/nextjs-i18n-seo [site URL or project path]
Oryginalny opis (EN)

Audit/fix Next.js i18n SEO for the App Router — crawlability, 307→301 redirects, locale URLs, sitemap, hreflang. Use when diagnosing lost PageRank or i18n redirect bugs in middleware.

Jak działa

  1. The Core Problem
  2. Phase 1: Audit the Site
  3. Phase 2: Fix the 307 → 301 Bug
  4. Phase 3 (Optional but Recommended): No-Prefix Default Locale
  5. Checklist
  6. Why Pages Router Appeared Better
  7. Real-World Comparison
Sekcje z nagłówków SKILL.md, w oryginale · 153 linii, 713 słów
Podgląd SKILL.md
---
name: nextjs-i18n-seo
description: Audit/fix Next.js i18n SEO for the App Router — crawlability, 307→301 redirects, locale URLs, sitemap, hreflang. Use when diagnosing lost PageRank or i18n redirect bugs in middleware.
user-invocable: true
argument-hint: "[site URL or project path]"
metadata:
  version: "1.0.0"
---

# Next.js i18n SEO Fix

Multilingual Next.js sites commonly ship with a crawlability-killing bug: locale redirects that use **307 Temporary** instead of **301 Permanent**. This means Googlebot never transfers PageRank to the actual indexed URL. Fix this first — it's a one-line change with immediate impact.

## The Core Problem

When a user (or Googlebot) hits `/hexagrams/14`, Next.js middleware redirects to `/en/hexagrams/14`. The default `NextResponse.redirect(url)` issues a **307 Temporary Redirect**. Google does not transfer PageRank on 307s. Result: any backlink to the clean URL is wasted.

**Pages Router** doesn't have this problem because `getStaticPaths` generates pages at their final URL with no redirect hop.

---

## Phase 1: Audit the Site

### 1. Check the redirect status code
```bash
curl -I https://example.com/some-page
# Look for: Location: and HTTP/2 301 vs 307
```

### 2. Check robots.txt
```
https://example.com/robots.txt
```
- All paths should be allowed (or only `/api/` blocked)
- Sitemap URL must be listed

### 3. Check the sitemap
```
https://example.com/sitemap.xml
```
- Are all pages listed with their final (locale-prefixed) URL?
- Are `alternates.languages` hreflang entries present?

### 4. Inspect the middleware
Look for `NextResponse.redirect(url)` — if no status code is passed, it's a 307.

---

## Phase 2: Fix the 307 → 301 Bug

**File: `src/middleware.ts`** (or `middleware.ts` at root)

```ts
// ❌ BEFORE — issues 307 Temporary Redirect
const response = NextResponse.redirect(newUrl);

// ✅ AFTER — issues 301 Permanent Redirect (passes PageRank)
const response = NextResponse.redirect(newUrl, 301);
```

Also fix any locale alias redirects (e.g. `zh-hans` → `zh-CN`) the same way — they should already be 301 if added later, but verify.

**Commit message:**
```
fix: change locale redirect from 307 to 301 for SEO PageRank transfer
```

---

## Phase 3 (Optional but Recommended): No-Prefix Default Locale

The locale prefix (`/en/hexagrams/14`) adds an extra path segment vs. `/hexagrams/14`. For English-first sites, removing the prefix from the default locale gives cleaner URLs and eliminates the redirect entirely for the primary language.

### Middleware changes

```ts
const defaultLocale = 'en';

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  const pathnameHasLocale = nonDefaultLocales.some(
    (l) => pathname.startsWith(`/${l}/`) || pathname === `/${l}`
  );

  // Already has a non-default locale — pass through
  if (pathnameHasLocale) return NextResponse.next();

  // Has explicit /en/ prefix — strip it (301 to clean URL)
  if (pathname.startsWith('/en/') || pathname === '/en') {
    const url = request.nextUrl.clone();
    url.pathname = pathname.replace(/^\/en/, '') || '/';
    return NextResponse.redirect(url, 301);
  }

  // No locale prefix — serve as default (English) directly, no redirect
  return NextResponse.next();
}
```

### generateStaticParams changes

```ts
// Layout and page components: include '' (no prefix) for English
export async function generateStaticParams() {
  return [
    { locale: '' },      // English — served at root paths
    { locale: 'zh-CN' },
    { locale: 'zh-TW' },
  ];
}
```

### Sitemap changes

```ts
// English URLs use no prefix
const enUrl = `${baseUrl}/hexagrams/${h.id}`;
// Other locales keep prefix
const zhCNUrl = `${baseUrl}/zh-CN/hexagrams/${h.id}`;
```

### Hreflang

```html
<link rel="alternate" hreflang="en" href="https://example.com/hexagrams/14" />
<link rel="alternate" hreflang="zh-CN" href="https://example.com/zh-CN/hexagrams/14" />
<link rel="alternate" hreflang="x-default" href="https://example.com/hexagrams/14" />
```

---

## Checklist

```
[ ] curl -I site.com/some-page → confirm 301 (not 307)
[ ] curl -I site.com/en/some-page → confirm 301 to /some-page (if no-prefix)
[ ] sitemap.xml lists final URLs (no redirect hops)
[ ] hreflang present on all pages with x-default
[ ] robots.txt allows all content paths, blocks /api/
[ ] generateStaticParams covers all locale variants
[ ] No cookie-only locale detection (Googlebot ignores cookies)
```

---

## Why Pages Router Appeared Better

Pages Router with `getStaticPaths` serves pages at their exact URL with **zero redirect hops**. App Router with locale middleware adds a redirect layer. The framework itself isn't the problem — the redirect type (307 vs 301) and the locale URL strategy are what matter. App Router with 301 redirects and/or no-prefix default locale matches or exceeds Pages Router crawlability.

---

## Real-World Comparison

| | sixlines.online (App Router) | bookofchanges.academy (Pages Router) |
|---|---|---|
| Hexagram URL | `/en/hexagrams/14` | `/hexagrams/14` |
| Redirect on clean URL | 307 → locale URL ❌ | none ✅ |
| Sitemap entries | 192 (64 × 3 locales) | 64 |
| Middleware on every req | yes | no |
| Fix | Change to 301 + consider no-prefix | — |

Wersje

W bazie nie ma innych skilli o nazwie nextjs-i18n-seo.

Migawka bazy z 28.10.2026 · wersja paczki c29beb2d2d74 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100optimise-seo
    Optymalizuje SEO i fundamenty techniczne aplikacji Next.js App Router: mapy witryny, robots, meta tagi, dane strukturalne, canonicale, przekierowania, hreflang, Core Web Vitals i nagłówki bezpieczeństwa.
  • 96seo-hreflang
    Audytuje lub generuje tagi hreflang dla wielojęzycznych witryn i międzynarodowego SEO.
  • 95auth0-nextjs
    Dodaje do Next.js logowanie, wylogowanie, chronione strony i middleware przez @auth0/nextjs-auth0, w App Router i Pages Router.
  • 100nextjs-i18n
    Opisuje dobre praktyki obsługi wielu języków w Next.js: routing lokalizacji i strategie wykrywania języka w App Router i Pages Router.
  • 90nextjs-seo
    Wdraża i audytuje SEO w Next.js App Router: metadane, mapy witryny, kanoniczne adresy, dane strukturalne i Core Web Vitals.
  • 90astro-i18n
    Wdraża i18n w Astro: routing lokalizacji, getRelativeLocaleUrl i getAbsoluteLocaleUrl, Astro.currentLocale oraz hreflang z mapą witryny.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.