← All articles

[ Blog ]

July 23, 2026

11 min read

Category: Insights

Website Not Loading in China? What It Actually Is

A client's site "wouldn't load" in mainland China. It wasn't the Great Firewall. Here's how I actually diagnosed a website not loading in China — and the fix.

PerformanceNext.jsVercelCloudflareChinaDebugging
Website Not Loading in China? What It Actually Is

A client pinged me with the kind of message that makes your stomach drop: their marketing site wouldn't load in China. Mainland users — real prospects — were getting a blank screen or an endless spinner. The immediate assumption, from everyone on the thread, was the obvious one: the Great Firewall is blocking us. That's almost always where these conversations start, and it's almost always wrong. This is the story of how I diagnosed a website not loading in China, why "blocked" was the wrong word, and the fix I actually shipped — plus the honest limits of what any fix can do against Chinese network conditions.

The stack, so you can map it to your own: a Next.js app on Vercel, a custom domain on a newer (non-mainstream) gTLD, proxied through Cloudflare, images served from Prismic's image CDN, video delivered via Mux, and a LinkedIn tracking pixel on every page. Every one of those pieces turned out to matter.

"Blocked in China" is usually the wrong diagnosis

Before touching anything, I made myself say the boring truth out loud: "won't load" is a symptom, not a cause. A page can fail to load for a dozen reasons that have nothing to do with censorship — a single render-blocking resource on a CDN with no China presence will do it. So the first job isn't to fix; it's to figure out which of the following is true:

  1. The domain is actually blocked (DNS pollution / SNI reset at the border).
  2. The domain resolves fine but the origin/CDN is slow or unreachable from certain carriers.
  3. The HTML loads but third-party resources (fonts, analytics, video, images) hang the page.

These need completely different fixes. Guessing wastes days. If you've read my piece on the hidden cost of a slow website, you know I'm allergic to shipping a "fix" before I've measured the actual failure — China is that lesson on hard mode.

The domain scare: a testing tool's blacklist ≠ censorship

My first instinct was to check the domain, so I ran it through 17ce.com, a popular China-based multi-node testing tool. It rejected the domain outright with a "url in black list" error. My pulse spiked — was the domain GFW-blocked at the registrar/TLD level?

No. That error is the tool's own blacklist, not the government's. Services like 17ce filter certain unusual TLDs and content categories as a matter of their own policy, and newer gTLDs get caught in that net constantly. A testing tool refusing your domain is not evidence that your domain is censored. This is the single most common false alarm I see teams panic over. The rule I now follow: never trust one tool's verdict, and specifically verify DNS resolution — because a truly blocked domain shows up as poisoned DNS, not as a vendor policy string.

Proper verification: multi-node ping from real mainland ISPs

I switched to ping.chinaz.com, which pings your domain from dozens of nodes sitting on actual mainland ISP networks. This is where the real picture appeared, and it was nothing like "blocked":

Vantage pointDNS resolutionReachabilityLatency
China Telecom nodesCorrect → Cloudflare IPsReachable~220–240 ms
China Unicom nodesCorrect → Cloudflare IPsReachable~220–240 ms
China Mobile nodesCorrect → Cloudflare IPsTimeout
Hong Kong nodeCorrectReachable<1–151 ms

Three things fell out of that table immediately:

  • DNS resolved correctly to Cloudflare's IPs from the mainland. No pollution, no redirect to a black-hole address. The domain was not blocked. That killed the entire "Great Firewall" theory in one row.
  • China Telecom and China Unicom could reach the site, but slowly (~230 ms). That's normal for Cloudflare's global anycast network, which has no mainland delivery nodes — traffic exits to Hong Kong, Japan, or the US west coast and comes back. High latency, but functional.
  • China Mobile timed out completely. China Mobile is the largest carrier and has the notoriously worst international transit of the three. The users who complained were, almost certainly, on China Mobile.

That last point is the lesson I now lead every China conversation with: always ask which carrier the complaining users are on. "It doesn't work in China" from a China Mobile user and from a China Telecom user are two different bug reports. Without that, you're debugging a ghost.

The real culprits: third-party CDNs, not the border

With the domain cleared, I inspected the site's network waterfall and found the actual reasons a website is slow in China here — and none of them were censorship of my domain:

  • Mux video (the biggest offender). Mux has no mainland delivery nodes, so its HLS streams either fail to start or buffer forever from China. On a site with a hero video, that alone is indistinguishable from "the site won't load" — the visitor stares at a frozen player above the fold and leaves.
  • Prismic's image CDN. Same story, lower severity: no mainland presence, so images arrive slowly and intermittently. A page that's mostly imagery feels broken even when the HTML is fine.
  • The LinkedIn tracking pixel. LinkedIn is fully blocked in China. The pixel is async and not render-blocking, so it doesn't freeze the page — but it's dead weight firing into a void, and there's no reason to keep it for that audience.
  • Baseline latency + China Mobile routing. ~230 ms round trips and China Mobile's bad international transit are simply not fixable from the application layer. No amount of code changes the physics of a packet leaving the mainland.

So the honest diagnosis wasn't "you're blocked." It was: your domain is fine, your carriers vary wildly, and your third-party media CDNs have no China presence — that's what's failing. If you've read Core Web Vitals for animation-heavy sites, this is the same principle in a hostile network: the third-party resources you don't control are usually what breaks the experience, and China just amplifies it to the point of total failure.

The fix: proxy what you can, route around what you can't

I had a hard constraint from the client: no legal paperwork, no domain change, no disrupting the content team's workflow. That rules out mainland hosting (more on why below) and rules out manually migrating every asset. Here's what I shipped instead.

Images — proxy Prismic through the main domain with edge caching

Rather than migrate images off Prismic (which would break the CMS workflow and create a permanent sync burden), I kept Prismic as the source of truth and changed only the delivery path. A rewrite on the main domain proxies image requests, and Cloudflare caches them aggressively at the edge:

// next.config.ts — proxy Prismic images behind our own domain
async rewrites() {
  return [
    {
      source: '/img/:path*',
      destination: 'https://images.prismic.io/:path*',
    },
  ];
}
# Cloudflare cache rule for /img/* — long edge TTL, so repeat
# visitors (and other mainland users) hit cache, not the origin CDN.
Cache-Control: public, max-age=31536000, immutable

The content team keeps uploading to Prismic exactly as before; only the URL the browser fetches changes. Proxying beat manual migration because migration would have meant re-pointing every CMS reference and babysitting a two-way sync forever.

Video — serve static MP4 to mainland visitors via Cloudflare R2

Mux HLS stays for every other market — adaptive bitrate is worth keeping. But for mainland visitors, a frozen HLS stream is the whole problem, so I detect them at the edge and serve a plain static MP4 instead. Mux can generate static renditions of any asset; I store those on Cloudflare R2 behind a subdomain and branch in Next.js middleware on Cloudflare's CF-IPCountry header:

// middleware.ts — route mainland China visitors to static MP4
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(req: NextRequest) {
  const country = req.headers.get('CF-IPCountry'); // set by Cloudflare
  const res = NextResponse.next();
  if (country === 'CN') {
    // App reads this to swap the <video> src to the R2 MP4 rendition
    res.headers.set('x-video-mode', 'mp4-static');
  }
  return res;
}

The trade-off is explicit and I put it in writing: mainland users lose adaptive bitrate. But a static MP4 that plays beats an adaptive stream that freezes. I chose R2 specifically because its egress is free — proxying video through Vercel would burn bandwidth quota alarmingly fast on a hero-video site.

Cleanup — drop the LinkedIn pixel for China traffic

Same CF-IPCountry branch: skip injecting the LinkedIn pixel for CN. It was firing into a blocked service anyway. Small win, zero cost.

Set expectations in writing — before you ship

This is the part most write-ups skip, and it's the most important. The fix addresses what's controllable: asset delivery. It does not — and cannot — fix the baseline ~230 ms latency or China Mobile's international routing. So before shipping, I sent the client a written note, not a verbal promise:

The most likely cause is third-party media with no China presence, plus poor China Mobile routing. This change should take the site from "won't load" to "loads, somewhat slowly" for most mainland users. It requires real-user verification — China network conditions vary by carrier, region, and time of day. Nothing short of mainland hosting guarantees fast performance, and that path has legal prerequisites (below).

Never write "guaranteed solution" for China. Write "most likely cause" and "requires real-user verification." That framing is what keeps a good client relationship intact when the results are — inevitably — mixed. Working with international clients is a core part of what I do as a creative developer for studios and agencies; managing expectations honestly is as much of the job as the code.

The infrastructure options I flagged (but didn't build)

For completeness, I laid out the heavier options as choices, not recommendations:

  • Mainland hosting / CDN — the only thing that truly fixes performance. It requires a Chinese legal entity, an ICP license (备案), and an ICP-eligible TLD. Here's the hidden trap: the client's newer gTLD is not MIIT-approved, so it's ineligible for ICP regardless of budget. Mainland hosting is off the table until they register an approved domain. This is why your choice of TLD is a China-market decision, not just a branding one.
  • A Hong Kong mirror — the middle path. No ICP needed, dramatically better latency than US/EU edges, though still not mainland-fast. A reasonable investment if China becomes a priority market.

Both were flagged as options with cost implications for the client to weigh, not things I implemented. Fix what you control first, measure with real users, then discuss infrastructure spend — in that order.

FAQ

Is my website blocked in China or just slow?

Verify DNS resolution from mainland nodes (use ping.chinaz.com or similar). If the domain resolves to your real CDN IPs, it is not blocked — you have a latency/reachability problem, not a censorship one. True blocking shows up as poisoned DNS or a reset connection during the TLS handshake, not as slow-but-working.

Why does my website work on some China networks but not others?

Because the three major carriers — China Telecom, China Unicom, and China Mobile — have very different international transit quality. China Mobile is the largest and typically the worst for foreign-hosted sites. Always ask a complaining user which carrier they're on before debugging.

Does using Vercel or Cloudflare cause China problems?

Not directly, but neither has mainland delivery nodes, so both incur high latency into China, and some Cloudflare/Vercel IPs have historically been affected by DNS pollution. A custom domain (not *.vercel.app) plus reducing reliance on China-inaccessible third-party CDNs solves most of it. See Vercel's own guidance below.

Do I need an ICP license?

Only if you want to host inside mainland China for real performance. An ICP license (备案) requires a Chinese legal entity and an MIIT-approved TLD. Many newer gTLDs are not approved and therefore can't get ICP at any price — check TLD eligibility before you commit to a domain if China matters to you.


If your site "won't load in China" and you need someone to actually diagnose it — separate real blocking from third-party-CDN failure, and ship a fix that respects your CMS workflow — that's the kind of international work I take on. See how I work with studios and agencies, or read more on shipping fast under pressure in the hidden cost of a slow website.

Sources: Vercel — Accessing Vercel-hosted sites from mainland China, Cloudflare — China Network overview, Mux — Static (MP4) renditions.

Related posts