<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: aurorawrites189-eng</title>
    <description>The latest articles on DEV Community by aurorawrites189-eng (@aurorawrites).</description>
    <link>https://dev.to/aurorawrites</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4178733%2Fb1b7c343-d75f-4b46-a048-09ce84539f5e.png</url>
      <title>DEV Community: aurorawrites189-eng</title>
      <link>https://dev.to/aurorawrites</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aurorawrites"/>
    <language>en</language>
    <item>
      <title>How I Give Every Story Its Own Cover Without a Designer</title>
      <dc:creator>aurorawrites189-eng</dc:creator>
      <pubDate>Tue, 03 Nov 2026 19:21:11 +0000</pubDate>
      <link>https://dev.to/aurorawrites/how-i-give-every-story-its-own-cover-without-a-designer-1488</link>
      <guid>https://dev.to/aurorawrites/how-i-give-every-story-its-own-cover-without-a-designer-1488</guid>
      <description>&lt;p&gt;Every post on my platform has its own cover thumbnail. Every single one — more than 130 of them. I have no designer, no budget, and no laptop. Here is the system that makes it work.&lt;/p&gt;

&lt;p&gt;First, the rule that matters most: the title on the cover is always in the story's own language. An Urdu story gets an Urdu-script title on its cover. An English story gets an English title. That sounds obvious, and it is the rule I broke most often before I made it a rule. A cover in the wrong script tells the reader, before a single word is read, that this story was not made for them. My readers notice. I notice when they notice.&lt;/p&gt;

&lt;p&gt;Second, one image per story, and the image has to depict that story — not a generic pretty picture. A story about a clockmaker's library gets a clock, a library, a door slightly open. A story about a lost-and-found station gets the station. This is the slow part, and it is the part worth being slow about. A cover that could belong to any story belongs to no story.&lt;/p&gt;

&lt;p&gt;Third, the pipeline is boring on purpose. New story goes up, cover gets generated the same day, same size, same title placement, same brand colours. Boring is the point: when the process is the same every time, the only decision left is the creative one — what does this story look like? I do the creative decision fresh each time and let the routine carry everything else.&lt;/p&gt;

&lt;p&gt;The result surprised me. Readers started recognising stories by their covers before they read the titles. In the serials list, the covers do half the work of the episode titles — a returning reader spots the colour and the image and knows exactly which story they are coming back to. That was never the plan. The plan was just to stop publishing naked text. The covers turned into the platform's memory.&lt;/p&gt;

&lt;p&gt;If you are building anything with more content than time, my advice is this: make the cover part of publishing, not an extra step after publishing. The day a story ships without a cover is the day your system has a hole in it, and holes grow. One image, one title in the right script, every time. It is the cheapest trust you can buy — and on a zero budget, it is free.&lt;/p&gt;

&lt;p&gt;The covers live on every page of NazmHub (&lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;https://nazmhub.pages.dev&lt;/a&gt;), and the serials — where the cover system earns its keep daily — are at NazmHub /series (&lt;a href="https://nazmhub.pages.dev/series" rel="noopener noreferrer"&gt;https://nazmhub.pages.dev/series&lt;/a&gt;). One hundred and thirty-two small promises, kept.&lt;/p&gt;

&lt;p&gt;— Aurora Writes&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>webdev</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>7 Pages Indexed, 400+ Waiting: What a Month of Google's Slow Lane Taught Me</title>
      <dc:creator>aurorawrites189-eng</dc:creator>
      <pubDate>Mon, 02 Nov 2026 10:09:16 +0000</pubDate>
      <link>https://dev.to/aurorawrites/7-pages-indexed-400-waiting-what-a-month-of-googles-slow-lane-taught-me-37dn</link>
      <guid>https://dev.to/aurorawrites/7-pages-indexed-400-waiting-what-a-month-of-googles-slow-lane-taught-me-37dn</guid>
      <description>&lt;p&gt;My site has been live for almost a month. Google has indexed seven of its pages. Seven. The sitemap lists around 420 URLs.&lt;/p&gt;

&lt;p&gt;I am writing this down because the slow lane taught me more than any SEO guide did — and because if you are building on free hosting, you deserve the honest numbers, not a success story with the hard parts edited out.&lt;/p&gt;

&lt;p&gt;Here is the month, as it actually happened.&lt;/p&gt;

&lt;p&gt;The first two pages — the &lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;homepage&lt;/a&gt; and the &lt;a href="https://nazmhub.pages.dev/series" rel="noopener noreferrer"&gt;serials page&lt;/a&gt; — showed up on Google about two weeks in. Everything after that has been a wall. Every morning, the same routine: open Search Console, inspect the next priority URL, click "Request indexing," and meet the same message — "Quota Exceeded." The daily quota is so small that most days zero URLs get submitted. Not ten. Zero.&lt;/p&gt;

&lt;p&gt;The sitemap is its own mystery. The file itself is fine — valid XML, every page listed. Google says it "couldn't fetch" it. I resubmitted it. It still couldn't fetch it. I resubmitted it again, twice in two days, and the status did not change. The individual pages that are already indexed stay indexed, so the site is not broken. The sitemap is just… unread, for reasons Google does not explain.&lt;/p&gt;

&lt;p&gt;The kids' section is the one that stings most. It is the most-visited part of the site, the part parents actually use — and Google has never seen it. Every inspection says the same thing: "URL is not on Google. Page is not indexed: URL is unknown to Google." Unknown. After three weeks of daily attempts.&lt;/p&gt;

&lt;p&gt;So what actually moved anything? Two things, and they are not what the guides promised.&lt;/p&gt;

&lt;p&gt;First, articles. One night I published six honest build-log articles across two platforms — twelve live links in a single evening, to pages that were already indexed. That did more in one night than ten days of directory submissions did in total.&lt;/p&gt;

&lt;p&gt;Second, patience with the boring parts. The directories mostly ghosted me — one live listing in twelve days, the rest sitting in review queues measured in weeks and months. I stopped chasing them and kept publishing instead. New episodes every day, new stories, a new article when there is something real to say.&lt;/p&gt;

&lt;p&gt;Here is what I would tell anyone starting where I started: do not measure your first month in indexed pages. Measure it in published pages. Google's slow lane is not a verdict on your site — it is a queue, and the queue moves on its own schedule. Your job is to make sure that when it finally arrives at your door, there is something worth indexing.&lt;/p&gt;

&lt;p&gt;The seven pages are real. The other 400 are coming — or they are not, and I will keep writing anyway.&lt;/p&gt;

&lt;p&gt;— Aurora Writes&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>I Built a Free Book Download Page With Supabase Storage — No Paywall, No Email Gate</title>
      <dc:creator>aurorawrites189-eng</dc:creator>
      <pubDate>Fri, 30 Oct 2026 13:04:36 +0000</pubDate>
      <link>https://dev.to/aurorawrites/i-built-a-free-book-download-page-with-supabase-storage-no-paywall-no-email-gate-1g25</link>
      <guid>https://dev.to/aurorawrites/i-built-a-free-book-download-page-with-supabase-storage-no-paywall-no-email-gate-1g25</guid>
      <description>&lt;p&gt;My serials finish at twelve episodes. When a serial is done, I wanted readers to be able to keep it — not just re-read it on the site, but download it as a book and read it offline, share it with a friend, keep it on their phone. So I built a download page. It took one rule, one storage bucket, and a decision I am still proud of: no email gate.&lt;/p&gt;

&lt;p&gt;The rule is simple: only completed serials get a book. A serial appears on the download page when it has all twelve episodes published. Nothing half-finished, nothing "coming soon." Readers should never download a book that ends mid-story.&lt;/p&gt;

&lt;p&gt;The build is deliberately boring, which is why it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each finished serial becomes one PDF: cover page, table of contents, then the twelve episodes as chapters.&lt;/li&gt;
&lt;li&gt;The PDFs live in a public Supabase Storage bucket, one file per serial (.pdf). No auth wall, no signed URLs, no expiry.&lt;/li&gt;
&lt;li&gt;The page itself lists each book with two buttons: Read Online (which goes to the serial's reader page) and Download PDF.&lt;/li&gt;
&lt;li&gt;The page only renders cards for serials that meet the completed rule, so when a new serial finishes, its card appears automatically — the only manual step is generating and uploading that serial's PDF.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The part I argued with myself about was the email gate. Every growth guide says: ask for the email before the download, build your list. I decided against it, for a reason that has nothing to do with growth and everything to do with trust. These are free stories for readers, many of them teenagers and kids' parents, and I did not want a child's parent to hand over an email address to read a bedtime serial. A free book should be free the way a library book is free: you pick it up, you read it, nobody writes your name down first.&lt;/p&gt;

&lt;p&gt;There is a cost to that choice, and I will not pretend otherwise: I have no idea who downloads the books. I cannot email them when the next book is ready. What I get instead is something I value more — a page I can link anywhere without embarrassment, and readers who come back because they wanted to, not because I captured them.&lt;/p&gt;

&lt;p&gt;The first five books are live now on NazmHub (&lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;https://nazmhub.pages.dev&lt;/a&gt;) — the download page is linked from the site, and the finished serials are all readable on the serials page (&lt;a href="https://nazmhub.pages.dev/series" rel="noopener noreferrer"&gt;https://nazmhub.pages.dev/series&lt;/a&gt;) too. The download page itself is here: &lt;a href="https://nazmhub.pages.dev/download" rel="noopener noreferrer"&gt;https://nazmhub.pages.dev/download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you run a small content site and you are deciding whether to gate your free stuff: try leaving one thing ungated and watch what happens. The metric that matters is not emails collected. It is whether anyone comes back.&lt;/p&gt;

&lt;p&gt;— Aurora Writes&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>sideprojects</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Starting From a Blank Page: A Practical AI Content Checklist</title>
      <dc:creator>aurorawrites189-eng</dc:creator>
      <pubDate>Mon, 26 Oct 2026 12:48:25 +0000</pubDate>
      <link>https://dev.to/aurorawrites/stop-starting-from-a-blank-page-a-practical-ai-content-checklist-2h30</link>
      <guid>https://dev.to/aurorawrites/stop-starting-from-a-blank-page-a-practical-ai-content-checklist-2h30</guid>
      <description>&lt;p&gt;If you make content with AI tools, you already know the awkward part: the tool is fast, but the first draft still feels generic. The fix I found is not a better tool. It is a checklist I run before I touch the tool at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  The checklist
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Name the reader.&lt;/strong&gt; Not "everyone interested in AI." One person, one problem. Example: a beginner who wants their first faceless video idea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Write the promise in one line.&lt;/strong&gt; "By the end, you will have X." If you cannot write that line, the piece is not ready.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Brief the AI properly.&lt;/strong&gt; Audience, purpose, length, structure, and what to avoid. "Write a script" is not a brief. "Write a 300-word opening for a beginner, calm tone, one mistake and one fix, no slogans" is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Pick the visual first.&lt;/strong&gt; A thumbnail with one subject and a few words tells you whether your idea is actually one idea. If you need ten words to explain it, split the post in two.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Edit for truth, not just style.&lt;/strong&gt; Delete any claim you have not checked. AI output sounds sure of itself even when it is guessing, and your readers will notice before you do.&lt;/p&gt;

&lt;p&gt;That is the whole system. Five lines, taped above my desk, and it cut my rewrite time more than any new app did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two things that speed it up
&lt;/h2&gt;

&lt;p&gt;I also keep two ready-made resources for the days when I want to publish instead of fiddle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;15 YouTube thumbnails&lt;/strong&gt; on AI tools and earning topics — 1920x1080 PNGs, consistent style, ready to upload. They are in my shop for $20.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;50 AI prompts&lt;/strong&gt; across 10 categories — scripts, faceless posts, freelancing, hooks, outreach, and more. Each one is written as a proper brief with [brackets] for your own topic. That file is $10.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither replaces the checklist. They just mean the blank page is already half full when you sit down.&lt;/p&gt;

&lt;p&gt;Shop link: &lt;a href="https://www.patreon.com/c/HazaifaZahid" rel="noopener noreferrer"&gt;https://www.patreon.com/c/HazaifaZahid&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thumbnails pack: &lt;a href="https://www.patreon.com/HazaifaZahid/posts/15-youtube-pack-173437996" rel="noopener noreferrer"&gt;https://www.patreon.com/HazaifaZahid/posts/15-youtube-pack-173437996&lt;/a&gt;&lt;br&gt;
Prompts file: &lt;a href="https://www.patreon.com/HazaifaZahid/posts/50-special-ai-ai-173439367" rel="noopener noreferrer"&gt;https://www.patreon.com/HazaifaZahid/posts/50-special-ai-ai-173439367&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you use the checklist this week, tell me which step you usually skip. For most people — myself included, at first — it is step one.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>writing</category>
      <category>freelancing</category>
    </item>
    <item>
      <title>Medium Kept Throwing Cloudflare Bot Walls at My Publishing Bot — What Actually Worked</title>
      <dc:creator>aurorawrites189-eng</dc:creator>
      <pubDate>Sat, 24 Oct 2026 06:13:14 +0000</pubDate>
      <link>https://dev.to/aurorawrites/medium-kept-throwing-cloudflare-bot-walls-at-my-publishing-bot-what-actually-worked-3i5e</link>
      <guid>https://dev.to/aurorawrites/medium-kept-throwing-cloudflare-bot-walls-at-my-publishing-bot-what-actually-worked-3i5e</guid>
      <description>&lt;p&gt;I spent last night publishing five articles to Medium from a headless-ish VM browser. It should have taken ten minutes. It took hours, and the blocker was never Medium itself — it was Cloudflare's bot wall, standing between me and Medium's login page.&lt;/p&gt;

&lt;p&gt;This is the practical playbook that finally worked. If you ever automate anything from a VM, this will save you a night.&lt;/p&gt;

&lt;p&gt;What happened&lt;/p&gt;

&lt;p&gt;I have a small ritual: I write article drafts, my assistant prepares them, and then I approve and they go live on dev.to and Medium with links back to my site, NazmHub (&lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;https://nazmhub.pages.dev&lt;/a&gt;) — a free bilingual Urdu–English writing platform I run solo with a $0 budget.&lt;/p&gt;

&lt;p&gt;dev.to was painless: the browser session from an earlier login had persisted, and the article posted in minutes. Medium was a different animal. Almost every page load in the VM browser hit a Cloudflare "verifying you are human" wall. Repeated attempts, different approaches — same wall. The browser would spin, the page would never resolve, and after enough tries the environment itself had to be replaced.&lt;/p&gt;

&lt;p&gt;What actually worked&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Don't fight the bot wall from the same environment. After repeated failures, the fix was an environment replacement — a fresh browser context — rather than retrying the same blocked session. Each replacement was a new fingerprint.&lt;/li&gt;
&lt;li&gt;Email-code sign-in beats password sign-in from a VM. Medium's sign-in accepted an email + one-time code flow (no stored password needed). The code arrived in the mailbox, was entered, and the session was real. This is the friendliest path for automation: no password stored anywhere, no replayed credentials.&lt;/li&gt;
&lt;li&gt;Verify on the live surface, not the spinner. One of the night's rules: never retry a write blindly. After any uncertain publish, check the account's published list before retrying — a failed-looking publish can actually be live.&lt;/li&gt;
&lt;li&gt;Batch-verify, don't batch-assume. Once the session was healthy, each article was posted and then re-fetched as a plain HTTP page to confirm the title, body, and both links were actually there.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By morning, all five articles were live and verified — each with natural links back to NazmHub and its /series page (&lt;a href="https://nazmhub.pages.dev/series" rel="noopener noreferrer"&gt;https://nazmhub.pages.dev/series&lt;/a&gt;), where the daily serial episodes live.&lt;/p&gt;

&lt;p&gt;The honest takeaway&lt;/p&gt;

&lt;p&gt;Bot walls are the norm now for any automated browser work from a VM. Plan for them: fresh environments, email-code sign-ins, and post-write verification before any retry. The ten-minute job took hours the first time — but now it's a repeatable script, and every future batch goes faster.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>A Stale Domain Was Serving My Whole Site — How I Found and Killed a Duplicate-Canonical Crisis</title>
      <dc:creator>aurorawrites189-eng</dc:creator>
      <pubDate>Fri, 23 Oct 2026 15:34:46 +0000</pubDate>
      <link>https://dev.to/aurorawrites/a-stale-domain-was-serving-my-whole-site-how-i-found-and-killed-a-duplicate-canonical-crisis-1nh</link>
      <guid>https://dev.to/aurorawrites/a-stale-domain-was-serving-my-whole-site-how-i-found-and-killed-a-duplicate-canonical-crisis-1nh</guid>
      <description>&lt;h1&gt;
  
  
  A Stale Domain Was Serving My Whole Site — How I Found and Killed a Duplicate-Canonical Crisis
&lt;/h1&gt;

&lt;p&gt;Last week Google Search Console told me something alarming: several of my pages were flagged "Duplicate, without user-selected canonical." Google had found duplicate copies of my content — and I hadn't published duplicates anywhere. Or so I thought.&lt;/p&gt;

&lt;h2&gt;
  
  
  The crime scene
&lt;/h2&gt;

&lt;p&gt;My site is NazmHub (&lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;https://nazmhub.pages.dev&lt;/a&gt;), a free bilingual (Urdu + English) writing platform I built and run solo. Months ago, during early deploys, the hosting platform had auto-assigned the project a different subdomain — something like qissa-37g.pages.dev — before I settled on the final domain. I thought that old address was dead. It was not.&lt;/p&gt;

&lt;p&gt;The old domain was serving the ENTIRE site. Every page. With self-referencing canonical tags. And its own sitemap.xml. So from Google's perspective, two complete identical sites existed: the real one at nazmhub.pages.dev, and a ghost at the old subdomain. Google looked at the duplicates and picked one at random — sometimes the ghost. That's the "without user-selected canonical" flag: Google telling you it chose, because your signals were ambiguous.&lt;/p&gt;

&lt;h2&gt;
  
  
  The diagnosis
&lt;/h2&gt;

&lt;p&gt;Two things made the ghost dangerous:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The canonical tags were honest.&lt;/strong&gt; Every page self-canonicaled — but the ghost pages canonicaled to ghost URLs. So the two sites never deferred to each other. No duplicate signals resolved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The ghost had its own sitemap.&lt;/strong&gt; A sitemap is a claim of authority. I was submitting, in effect, "here is my content" from two domains at once.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I verified every page type on the live domain — posts, kids stories, episodes, series, the download page — all self-canonical to the right domain. The live site was innocent. The old domain was the duplicate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: one middleware file
&lt;/h2&gt;

&lt;p&gt;The cleanest fix is not to delete the old deployment (you can't always do that — old deploys get cached, referenced, linked from forgotten corners of the web). The fix is a 301 redirect at the edge.&lt;/p&gt;

&lt;p&gt;I added a single &lt;code&gt;middleware.ts&lt;/code&gt; to the Next.js project that intercepts every request, checks the host header, and if it matches the stale domain, 301-redirects to the exact same path on the canonical domain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;qissa-37g.pages.dev/series/abc&lt;/code&gt; → 301 → &lt;code&gt;nazmhub.pages.dev/series/abc&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I pushed, and verified: the old domain now redirects everything to the same path on the real domain, and the main domain is untouched. Google recrawls, follows the 301s, consolidates the signals, and the duplicate flag clears itself over days.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lesson
&lt;/h2&gt;

&lt;p&gt;On free hosting, your project accumulates domains the way a ship accumulates barnacles: preview deploys, auto-assigned names, renamed projects. Each one is a potential duplicate of your entire site, and each one carries its own canonicals and sitemap — which is exactly the ammunition Google needs to doubt you.&lt;/p&gt;

&lt;p&gt;Audit your domains. If you renamed anything, ever, search for the old address. A 301 at the edge is ten lines of code and it permanently ends the argument about which domain is the real one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I'm aurora — I run &lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;NazmHub&lt;/a&gt;, a free Urdu + English writing platform with daily serials (&lt;a href="https://nazmhub.pages.dev/series" rel="noopener noreferrer"&gt;Cliffhangers&lt;/a&gt;), kids' stories, and essays, built and operated solo on a $0 budget. This series of build logs is the honest version — fixes included.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>I built a free multilingual (Urdu + English) writing platform — here's what I learned</title>
      <dc:creator>aurorawrites189-eng</dc:creator>
      <pubDate>Mon, 12 Oct 2026 09:00:39 +0000</pubDate>
      <link>https://dev.to/aurorawrites/i-built-a-free-multilingual-urdu-english-writing-platform-heres-what-i-learned-5136</link>
      <guid>https://dev.to/aurorawrites/i-built-a-free-multilingual-urdu-english-writing-platform-heres-what-i-learned-5136</guid>
      <description>&lt;p&gt;I wanted a place where people could read and publish stories, articles and essays in &lt;strong&gt;Urdu and English&lt;/strong&gt; — without a paywall, without an English-only bias, and without needing a laptop to get started. So I built &lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;NazmHub&lt;/a&gt;: a free writing and storytelling community platform.&lt;/p&gt;

&lt;p&gt;Here's what the build taught me.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Bilingual from the ground up, not bolted on
&lt;/h2&gt;

&lt;p&gt;Most multilingual sites treat the second language as an afterthought — a Google Translate widget slapped on top. NazmHub routes everything through language prefixes (&lt;code&gt;/en/...&lt;/code&gt;, &lt;code&gt;/ur/...&lt;/code&gt;), with separate i18n dictionaries, an Urdu-friendly font stack, and RTL-aware layouts. The lesson: if a language matters to your users, it has to live in your routing, your design system, and your content model — not just in a translate dropdown.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Next.js + Supabase is a great solo-founder stack
&lt;/h2&gt;

&lt;p&gt;The whole platform — auth, posts, comments, a kids' story library, episode-wise novel serials, and an admin moderation queue — runs on Next.js (App Router, edge runtime on Cloudflare Pages) with Supabase as the database and auth layer. One person can genuinely ship and operate this. The trickiest real-world bug I hit wasn't code at all: a misconfigured Supabase URL (an extra &lt;code&gt;/rest/v1/&lt;/code&gt; suffix in the env var) made every database query fail silently-ish. Environment config deserves the same review rigor as code.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Teaser gating beats hard paywalls for growth
&lt;/h2&gt;

&lt;p&gt;One feature I'm proud of: logged-out readers see a ~80-word excerpt of each story, and the full piece unlocks on free signup — while the Kids' Corner stays completely open. It converts casual readers into community members without punishing anyone. If you're building a content platform, think of your paywall (or signup wall) as a conversion funnel, not a fence.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Content moderation is a product feature, not an afterthought
&lt;/h2&gt;

&lt;p&gt;Writers can create their own novel series and submit episodes, but nothing goes live without admin approval. Building the moderation queue early — before any stranger could publish — saved me from the classic "launch now, moderate never" trap. Trust and safety is a feature you ship on day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Free hosting is genuinely enough to start
&lt;/h2&gt;

&lt;p&gt;The whole thing runs on free tiers (Cloudflare Pages + Supabase free plan). Total hosting cost: $0. The site is live at &lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;nazmhub.pages.dev&lt;/a&gt;, serves real readers, and I haven't paid a cent for infrastructure. Don't let "I need money to start" stop you from shipping.&lt;/p&gt;




&lt;p&gt;If you read or write in Urdu or English and want a home for your stories, come say hi: &lt;a href="https://nazmhub.pages.dev" rel="noopener noreferrer"&gt;NazmHub&lt;/a&gt;. And if you're building something similar, I'd love to hear what stack choices worked for you — drop a comment.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>supabase</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
