
PDFWix
25+ PDF Web Tools. No Download. No Usage Limit.
I'm Parag. I build software for a living and I've wanted to ship something of my own for a while. Two weeks ago I started building PDFWix — a free PDF toolkit (merge, split, compress, convert, etc.) competing in one of the most crowded niches on the internet. iLovePDF, SmallPDF, Adobe, PDF24 are all giants. I figured if I was going to fail, at least I'd learn something.
I'm writing this two days before the soft launch and the site still isn't fully working. So this is less of a victory lap and more of a "here's everything that broke and what I'd do differently" post.
Why even try this?
Honest answer: I was tired of "free" PDF tools that aren't actually free. SmallPDF caps you at 2 files per day. iLovePDF makes you sign up after a couple of operations. PDF24's free tier is fine but the UX feels like 2014. There's a real gap for "tools that just work, don't ask for your email, and don't add a watermark."
The other reason was personal. I wanted to see if a solo developer could realistically ship a polished product against incumbents with 10+ years of authority. Spoiler: you can get further than I expected, but the journey involves a lot more debugging than the indie hacker tweets suggest.
The SEO infrastructure rabbit hole
I went with a React SPA stack for the front-end, which turned out to be the single decision that ate the most of my time. Google can technically index JavaScript, but for a brand-new domain with no authority, the rendering queue is slow and unreliable. Bing barely renders JS at all. AI crawlers like ChatGPT and Perplexity don't render JS in any meaningful way.
By the time I figured this out, I had ~190 pages built. I had three options:
Migrate to Next.js or Astro (1-2 weeks of rebuild)
Use a prerendering service to serve static HTML to bots
Skip prerendering and pray Google's JS rendering treats me well
I picked option 2 — Cloudflare Worker + Prerender.io.
The setup looks simple on paper:
Cloudflare proxies all traffic to my domain
A Worker sits at the edge and detects user agents
Bots get HTML pre-rendered by Prerender.io
Humans get the React SPA from origin
This took me the better part of two days to get working. Things that broke along the way:
1. The Worker code didn't read environment variables correctly. Modern Cloudflare Workers using export default don't expose env vars as globals — they come through as env.PRERENDER_TOKEN. My first version referenced PRERENDER_TOKEN directly, which is undefined in module syntax. Bot detection ran fine, but the prerender check if (env.PRERENDER_TOKEN) was effectively if (undefined), and bots fell through to the SPA. I caught this only when Prerender.io's dashboard showed zero cached pages despite Google supposedly crawling my site.
2. DNS records pointed to the wrong host. I'd previously parked the domain elsewhere and hadn't updated the A records. Cloudflare was proxying, but the Worker route wasn't activating because of how the records were configured. Fix was switching to a CNAME pointing at the right origin, with the orange-cloud proxy enabled.
3. Infinite redirect loop in the browser. Once the Worker started routing correctly, the browser-facing version started looping. The origin saw requests with Host: www.pdfwix.com and tried to "fix" the canonical — sending a 302 back to www.pdfwix.com, which hit the Worker, which fetched the origin, which redirected again. Fix was to set redirect: "follow" in the Worker's fetch options so it followed redirects internally instead of passing them to the browser, plus rewriting Set-Cookie headers to use pdfwix.com instead of the origin domain (otherwise Chrome rejects them as third-party cookies).
4. robots.txt and sitemap.xml were going through Prerender.io. Prerender.io can't render .txt or .xml files — it's designed for HTML. So Googlebot was getting empty responses for the two files it cares about most. Fix was an explicit allowlist in the Worker:
javascript
const NEVER_PRERENDER_PATHS = new Set([ "/robots.txt", "/sitemap.xml", "/favicon.ico", "/manifest.json", ]);
5. Default robots.txt blocked AI crawlers. Cloudflare offers an "Instruct AI bot traffic with robots.txt" option during setup. The default it generates blocks GPTBot, ClaudeBot, Google-Extended, and Meta's crawler. If you want AI search visibility (which I do), you have to manually allow them. I caught this only after running curl on my own robots.txt.
What I'd do differently
If I were starting this project fresh tomorrow:
Use Astro or Next.js, not a SPA framework. Spending time on Worker + Prerender.io plumbing was time I could've spent writing content. SSR/SSG for SEO sites is a solved problem and not worth reinventing.
Don't build 18 tool pages before launching one. Each tool page is supposed to have unique, deeply useful content — and templated boilerplate doesn't cut it for ranking against incumbents. Better to launch with 3 polished pages than 18 thin ones.
Set up tracking on day one. I shipped before installing Google Analytics, Search Console, conversion tracking, or proper UTM strategy. Trying to add it now after submitting to directories means I have no idea which channels are actually working.
Pick the differentiator before writing copy, not after. I started with "free PDF tools" as the pitch. That's iLovePDF's pitch from 2012. Halfway through I realized the real differentiator was "no signup, no watermark, no daily limits, no upsell" — and I had to rewrite a lot of copy to match that positioning. Should've nailed it on day one.
Pick a niche even within a saturated niche. "Free PDF tools" is too broad to win. "Free PDF tools for accountants" or "Free PDF tools that don't require signup" are positions you can actually defend. The narrower the wedge, the better the chance.
Where things stand now
The site loads. The Worker correctly routes bots to Prerender.io and humans to origin. Google's Rich Results Test shows my structured data validates cleanly. Five tool pages have unique content I'm not embarrassed by. The other 13 still need real rewrites.
Soft launch is in 2 days. I expect some things to break. I expect some of the SEO setup to backfire in ways I haven't predicted. I expect to feel completely overwhelmed when the first 100 users find bugs simultaneously.
If you want to see what came out of all this, it's at pdfwix.com. I'd genuinely love feedback — what's broken, what's missing, what doesn't make sense. Comments here or DMs, whatever works.
If you're thinking of building a similar SEO-driven site on a SPA framework: don't, unless you've already worked through the Worker + Prerender.io playbook above.
I'll post a follow-up in 30 days with actual numbers — traffic, conversions, what worked, what didn't. Hold me to it.
Thanks for reading.
— Parag
About
I needed to merge 3 PDFs and every "free" site blocked me until I paid or signed up. So I built PDFWix — 18 PDF tools that are actually free. No signup, no watermarks, no daily limits.

Comment