I am writing this at the end of the longest single day in Pawtrips history.
I am also sick. Genuinely, properly sick. The kind where your head feels like it is filled with wet sand and your body is telling you in very clear terms to lie down and stop. I have been fighting this for a few days now and today it hit its peak.
I built more today than on any previous day. The irony is becoming a pattern.
What changed today
If you visited Pawtrips yesterday and you visit it today, you are looking at a different website. Not cosmetically different. Architecturally different.
Yesterday Pawtrips ran on an Intel NUC on my office desk in Brisbane. A home server, residential internet, a Cloudflare tunnel routing traffic to a Next.js app running on hardware I can physically touch.
Today Pawtrips runs on Vercel. The database lives on Neon. The code deploys automatically every time I push to GitHub. There is no NUC in the loop anymore.
That is not a small change. That is the foundation shifting underneath everything.
Why we migrated
The NUC has been extraordinary. I want to say that clearly before I explain why we left it.
Building a platform with 115+ pages, a real database, authenticated email, and a proper domain on a home server that cost a fraction of cloud hosting is something I am genuinely proud of. It worked. It ran. It handled everything I threw at it.
The problem is what happens next.
Google ranking depends on uptime. Affiliate income depends on people being able to reach the site. A home server connected to residential internet is a single point of failure. Power outage, hardware failure, internet drop, NUC needs a restart. All of it takes the site down. All of it potentially costs rankings that take months to rebuild.
The migration path was always mapped. Next.js to Vercel. PostgreSQL to Neon. I just needed a reason to move.
The reason arrived when I looked at the NUC uptime logs and realised that three brief outages over the past week had each taken the site offline for between five and twenty minutes. On a brand new site trying to get indexed by Google, that is not acceptable.
So we moved. On a Thursday evening. While I was sick. Because the right time to fix infrastructure is not when you feel like it. It is when it needs fixing.
The migration itself
I want to be honest about what this involved because I think there is a version of this story that makes it sound clean and easy. It was not.
The Neon database needed three tables recreated from a schema dump. The Vercel environment variables needed setting individually. The DNS needed cutting over from the Cloudflare Tunnel to Vercel's nameservers. The Brevo email integration had an IP restriction enabled that silently blocked all signups until I found it and disabled it.
The favicon appeared twice because there were two copies in two different locations and Next.js was confused about which one to use.
A GitHub token got accidentally committed to the repository URL in the git config. Caught it, revoked it, regenerated it, cleaned the config.
Errors. All of them fixable. None of them catastrophic. But each one a reminder that migrations are never just flipping a switch. They are a series of small problems you find and solve until the thing works.
The site went live on Vercel at the end of a session that took several hours. Email signups tested successfully. Database writing correctly. Favicon clean.
The image system came out
This one was a deliberate decision and the right one even though it stings a little.
Pawtrips has been using an Unsplash image cache to pull hero photos for posts. It was elegant when I built it. On the free tier of Unsplash the rate limits are tight enough that production traffic would hit the ceiling fast.
Rather than migrate a system that would immediately need replacing, I stripped it out before the Vercel deploy. Clean build. No image dependencies. Posts render without hero images for now.
It is not a permanent state. The plan is a headless CMS, probably Storyblok or Sanity, that lets me add images visually without touching code. That is a proper project for a future session. The right move today was to not drag a broken system into a new infrastructure.
The homepage got rebuilt
While the migration was being tested, I rebuilt the homepage from scratch.
The old homepage said "we are building something Australia has never had" in the hero section. That framing made sense on day one when there was nothing to show. On day six with 115 guides live it was actively misleading. We have built something. The homepage should show that.
The new homepage leads with what Pawtrips actually is. Australia's honest pet travel guide. Trust bar showing guides live, states covered, 100% independent. Email capture that leads with the checklist offer. A categories grid that links directly into the content. The vision section demoted to "where we are headed" rather than the lead.
The categories grid was the change I am most proud of. Six cards linking to Destination Guides, State Guides, Pet Health, Breed Guides, Travel Gear, and Pet Laws. It shows the depth of what exists. It gives visitors a reason to explore beyond the homepage. And it fixes one of the things that had been quietly bothering me since the early days, the site felt like a coming soon page even as the content grew.
The lead magnet
This one took longer than it should have and I want to explain why because the lesson is worth recording.
The pet travel checklist PDF had been on the to-do list for a while. A one-page branded checklist: before you book, packing essentials, health and safety, on the road, at your stay. Simple. Useful. Something people would actually download.
The build itself was straightforward. WeasyPrint, forest green and gold design, five sections, downloadable links to the relevant guides on the site.
The complication was wiring it into the signup flow correctly. The EmailCapture component needed a success state that delivered the PDF. That required an anchor tag with a download attribute. Simple JSX. Except the anchor tag opening got dropped in the file write and the build failed on Vercel with a syntax error.
This is the fourth time a JSX anchor tag issue has caused a failed build during Pawtrips development. I have now written a rule for myself: always write the full anchor tag on a single line where possible. Never orphan the attributes. The time it costs to write it carefully is nothing compared to the time a failed deploy costs.
The checklist is live. Signup, get the PDF immediately. No email sequence required for the download itself. Clean and instant.
Amazon affiliate links in twelve posts
This is the one that will actually make money.
When I looked at the state of Pawtrips yesterday, there was a gap that bothered me. Over 100 posts live. Almost none of them monetised. The winter gear post had product cards. That was it.
Today we added Amazon affiliate product cards to twelve posts. The accommodation guide. The packing guide. Paralysis ticks. Heatstroke. Calm-on-long-drives. The winter care post. Six products each on average.
Every post the checklist PDF links to now has product cards. That closes a funnel I had not planned properly but should have. Person signs up, downloads checklist, checklist links to guides, guides have product recommendations, products earn commission. The whole chain is connected.
The process was not clean. The heatstroke post had a warnings array after the products array and I missed the required comma between them. The build failed three times across the session for variations of the same structural issue. I now run a grep for warnings arrays before adding products to any post. Lesson learned the hard way and remembered permanently.
The errors deserve their own section
Because I think the honest account of building in public is not just the wins.
The Vercel build failed four times today on separate issues. The JSX anchor tag. The missing comma before warnings. The emoji escape codes that rendered as raw unicode strings instead of actual icons on the homepage. Each one was fixable. Each one required debugging while sick and tired and slightly frustrated.
The emoji issue is the one I want to talk about specifically because it is the kind of thing that looks terrible on a live site and happens for a reason that is completely invisible until you see it.
The category grid on the new homepage had emojis for each category. I wrote them using Python unicode escape sequences in the file. They looked fine in the code. On the live site every emoji showed as its raw escape code. U0001F3D6. Right there on the homepage in front of anyone who visited.
The fix was replacing every escape sequence with the actual unicode character. Two minutes. But the two minutes only come after you notice it is broken, understand why, and know what to change. The lesson is to test emoji rendering on the actual deployed site before considering it done. They do not always survive the file write intact.
The announcement bar
Small addition but one I think will have a real effect on traffic to the winter care post.
A slim gold bar above the navigation. Forest green text. One line: winter is here, is your dog ready, see our winter care guide. Dismissable with an X.
The winter care post is timely. June is here. Southern Australia is cold. People are searching for dog coats, joint supplements, self-warming beds. The announcement bar pushes them toward a post that is perfectly positioned for those searches and has affiliate product cards to convert the visit into income.
There were four separate deploy failures before the announcement bar rendered correctly. Invalid HTML structure, wrong component placement, body tag issues. Each one found and fixed. The bar is live now and looks clean.
On building while sick
I want to be careful about how I write this section.
I am not romanticising working through illness. I am not suggesting it is admirable or that you should do it. Rest is real. Recovery matters. If you are sick you should rest.
What I want to record honestly is what it actually felt like to build through it.
Everything took longer. Commands that should have been immediate needed checking twice. Errors that would have been obvious when healthy took longer to see. The patience required to debug a failed build at the end of a long day when your head hurts is a different kind of patience than debugging fresh.
And I kept going anyway. Not because I am tough. Because I could not look at the gap between what Pawtrips was yesterday and what it needed to be today and choose to let it sit there for another day.
The NUC migration needed to happen. The homepage needed to change. The affiliate links needed to go in. These were not optional improvements. They were the difference between a site that earns and a site that watches potential revenue scroll past uncaptured.
Pawtrips is not a hobby. It is a business I am building toward being a meaningful income. That context changes what sick days feel like.
Where we actually are
Pawtrips is six days old.
It runs on Vercel now. Zero-downtime deploys. Automatic on every push. The NUC is still running the old version but it is no longer serving live traffic. Google will never see a downtime again from my home internet dropping.
The database is on Neon. Hosted, reliable, not dependent on a drive in my office.
115 pages live. 8 categories. Amazon affiliate links in 12 posts. A lead magnet that delivers immediately on signup. A homepage that shows what Pawtrips actually is rather than what it was going to be.
Email signups are flowing. Brevo is receiving them. The list is growing.
And I have a headache and a box of tissues next to the keyboard.
What comes next
The CMS project is the big one on the horizon. Storyblok or Sanity. Visual editing. Drag and drop images. The ability to update the site without opening a code editor. That is what turns Pawtrips from a project I run into a platform I can genuinely scale.
Before that: the Brevo welcome email sequence needs building. New subscribers should receive the checklist by email as well as the immediate download. Two affiliate applications, Lyka and crumb.pet, are pending responses. Commission Factory reapplication in four to six weeks.
The content pipeline continues. More affiliate links in existing posts. The remaining high-value posts that need product cards. The deals page that is planned. The monthly recommendation section once analytics are set up.
But tonight none of that. Tonight I take the painkillers and actually rest.
Day six is done.
It was the biggest single day in Pawtrips history.
We built it while sick.
I would not change a thing.
If this resonated with you, share it with someone who has a dog and a dream.
Join the pack 🐾