Illustrative case study

A fictional business. The figures are a modelled scenario, not a client result.

종이연 코믹스 · 서울Paperkite Comics · Webcomic platform · Seoul

How a webcomic platform made 12,000 episodes crawlable in three languages

+9,600indexed episodes

ep-001 ✓ep-4,800 ✓ep-12,000 ✓10,020색인!

모든 이야기는 문제에서 시작한다Every story starts with a problem

문제The challenge

12,000 episodes. Google could see 420.

Infinite-scroll reader pages with client-side rendering meant Google indexed only series covers, never episodes, in Korean, English or Indonesian.

Paperkite publishes 140 series in Korean, with English and Indonesian translations a week behind. Readers loved the endless vertical scroll; crawlers got an empty page and a cover image. Search traffic came almost entirely from series names — nobody searching for “episode 41” or a genre in Bahasa ever found them.

Googlebot (illustrative)표지만 보여요… 에피소드는 어디 있죠?I can only see covers… where are the episodes?

그래서 우리는 뷰어를 열었다So we opened up the reader

진단Audit & diagnosis

Five things the crawler tripped over

Render snapshots of 2,000 sampled episodes, four weeks of server logs and a full hreflang crawl across all three languages.

치명적 Critical

빈 HTMLEpisodes shipped as an empty shell

The reader route returned a 2 KB HTML shell; panels, title and episode number arrived only after a 1.4 MB client bundle ran. Googlebot's rendered snapshot timed out on 71% of sampled episodes.

치명적 Critical

무한 스크롤Infinite scroll with no addressable pages

Episode 2 onwards loaded on scroll via fetch with no URL change. 11,600 of 12,000 episodes had no crawlable link pointing at them anywhere on the site.

높음 High

언어 혼선Hreflang pointing at the series cover

Every translated episode declared the Korean series cover as its alternate, and ID pages lacked a return tag: 3,140 hreflang errors, with Indonesian readers landing on Korean pages.

높음 High

느린 반응620 ms taps on the reader

A scroll listener re-measured every panel image on each frame, and the next-episode button waited on an analytics call. p75 INP on mobile sat at 620 ms.

중간 Medium

중복Canonicals collapsing to page one

Comment pagination (?page=2…40) canonicalised to the series cover, telling Google every episode and every comment page was a duplicate of it.

크롤러의 시선What Googlebot received

<h1>Paper Kite · Episode 41</h1>
<p>The wind changes over Namsan…</p>
<img alt="Panel 1: Ha-eun lifts the kite"
     width="720" height="1180" …>
<nav>
  <a href="…/ep-40">Previous</a>
  <a href="…/ep-42">Next</a>
</nav>
<a href="…/archive?page=1">All episodes</a>

Title, synopsis, alt text and neighbour links in the first response. Indexable on the first crawl.

작전 개시The plan

전략Strategy

Keep the endless scroll. Give every episode an address.

Built on our Signal technical SEO plan: four tactics, shipped language by language so each fix could be measured on its own.

Tactic 01

JavaScript rendering · 서버 렌더링

Moved the reader to server components: episode title, number, synopsis, panel alt text and next/previous links are in the first HTML byte. The panel images stream lazily below the first three.

Tactic 02

Pagination · 페이지 나누기

Each episode got its own clean URL (/series/slug/ep-41) with plain <a> links to neighbours, plus a paginated series archive at 50 episodes per page. Scroll still feels endless, but the URL updates with history.replaceState as each episode boundary passes.

Tactic 03

Hreflang · 언어 태그

Rebuilt the hreflang cluster per episode — ko, en, id and x-default — generated from the translation table so every alternate is reciprocal. Untranslated episodes simply omit their tag instead of pointing at a cover.

Tactic 04

Core Web Vitals · 웹 바이탈

Replaced the per-frame scroll listener with an IntersectionObserver, reserved panel heights from stored dimensions, deferred analytics with requestIdleCallback and split the comments widget out of the reader bundle.

한 화, 세 언어One episode, three languages

제41화 · 바람의 방향

드디어… 바람이 바뀌었어!

<head> · /ko/series/paper-kite/ep-41

<link rel="canonical"
  href="/ko/series/paper-kite/ep-41">
<link rel="alternate" hreflang="ko"
  href="/ko/series/paper-kite/ep-41">
<link rel="alternate" hreflang="en"
  href="/en/series/paper-kite/ep-41">
<link rel="alternate" hreflang="id"
  href="/id/series/paper-kite/ep-41">
<link rel="alternate" hreflang="x-default"
  href="/ko/series/paper-kite/ep-41">

Every version lists every other — and itself. Before, all three pointed at the Korean series cover.

연재 일정8 months, one episode at a time

Month-by-month timeline

  1. 제1화 · 진단

    Month 1 · Diagnosis

    Render snapshots of 2,000 sampled episodes, log-file analysis, and a hreflang crawl across all three languages.

    420 episodes indexed

  2. 제2화 · 설계

    Month 2 · URL architecture

    Episode URL scheme, archive pagination and canonical rules agreed with the engineering team; redirect map for legacy hash URLs.

    610 episodes indexed

  3. 제3화 · 서버

    Month 3 · Server rendering ships

    Reader moved to server components for Korean first. Rendered HTML now carries title, number and neighbour links.

    1,450 episodes indexed

  4. 제4화 · 번역

    Month 4 · Hreflang rebuild

    Reciprocal ko / en / id / x-default clusters generated from the translation table; Indonesian sitemap split out.

    3,200 episodes indexed

  5. 제5화 · 속도

    Month 5 · INP sprint

    Scroll listener removed, analytics deferred, comments split out. p75 INP drops below 250 ms.

    5,400 episodes indexed

  6. 제6화 · 확장

    Month 6 · English and Indonesian

    Server rendering rolled out to EN and ID readers; archive pages submitted in per-language sitemaps.

    7,600 episodes indexed

  7. 제7화 · 정리

    Month 7 · Clean-up

    Comment pagination given self-canonicals and noindex beyond page 5; orphaned episodes linked from archive pages.

    9,100 episodes indexed

  8. 제8화 · 완결

    Month 8 · Steady state

    10,020 episodes indexed. Monitoring alerts on render-snapshot size and hreflang error counts, handed over to the in-house team.

    10,020 episodes indexed

8개월 후…8 months later…

결과Results

+9,600 indexed episodes

02.5k5k7.5k10k1화2화3화4화5화6화7화8화42010,020

Indexed episodes at the end of each month (modelled Search Console coverage).

420 → 10,020

Indexed episodes

+264%

Organic readers

620ms → 160ms

INP

0800ms

-96%

Hreflang errors

  • 1화3,140
  • 2화3,090
  • 3화2,210
  • 4화1,180
  • 5화540
  • 6화260
  • 7화160
  • 8화126

Modelled scenario for a fictional business — not a client result. Rankings and traffic are never guaranteed; see our Terms.

검색 순위Rankings by language

Google positions for sample queries before and after, by language
QueryLangMonthly searchesBeforeAfter
로맨스 판타지 웹툰 무료KO22,000not ranked4
종이연 웹툰 41화KO3,600not ranked1
webtoon romance fantasy freeEN14,800486
read korean webcomic englishEN9,900not ranked9
baca komik korea bahasa indonesiaID18,100not ranked3
webtoon gratis episode terbaruID12,100627
slice of life webtoon recommendationsEN5,400315

다음 화에 계속To be continued — in your story

Get a plan like this

Pages Google can’t render, languages that point at each other wrong, readers who tap and wait. Signal fixes the plumbing.

← More case studies