A few years ago, at an agency I worked at, we launched a corporate WordPress site by migrating the whole database from our development environment to production. The demo had looked perfect. The client had signed off.
The reports started coming in almost immediately, first from our own post-launch review, then from the client's side as they clicked through their brand-new site. Buttons that led nowhere. Images that wouldn't load. Our local dev URLs were hardcoded all over the site: pasted into button links, baked into image paths. Nothing had looked wrong, because on our machines, those URLs worked fine.
Three of us spent the rest of that day clicking through every single page, hunting for leftovers. We fixed what we found and quietly hoped we'd found them all. No one yelled at us. The consequence was quieter than that, and heavier: the string of post-launch defects was treated as a formal incident, with a permanent entry in the company's internal incident list. That entry doesn't expire. As far as I know, it's still there.
The handoff problem
Handoff is the moment responsibility changes hands: the most dangerous, and the most important, moment in the entire project.
Clients trust the agency. They take it for granted, as they should, that the site they're receiving is solid. But that trust is easier to betray than anyone likes to admit. The moment a client finds a defect, doubt creeps in. However hard the team worked, a single careless leftover is enough to make them wonder: what does the quality of this site really look like?
There's a structural reason this happens. While you're building, you're in the admin every day, and you'd notice a stray test post, a debug flag, a weird setting. After handoff, the person in the admin is your client. They edit content, upload images, and take everything at face value. The leftovers that were invisible in the demo are now their discoveries.
Most launch checklists focus on whether the site works. A handoff checklist asks a different question: what will the client find that I should have found first?
Here's the list I wish I'd had back then. Every item includes how to check it manually, no tools required.
1. Content cleanup
Test posts. About an hour after one delivery, a chat message arrived from the client: "What is this 'test test' page?" Chat messages don't carry tone, but I could feel the reaction through the screen. Test content is harmless to the site and terrible for trust.
How to check: In the admin, go to Posts and Pages, sort by date, and scan for anything you created as filler: "test", lorem ipsum, placeholder drafts. Don't forget custom post types and the trash.
Unused media. On another project, a stock photo was still carrying the vendor's watermark. We had never replaced it with the licensed version. The client spotted it right before delivery, which is one step better than after delivery, and still one step worse than us spotting it ourselves.
How to check: Open Media Library, switch to list view, and go through everything uploaded during development. Look for placeholders, duplicates, screenshots, and anything watermarked.
Temporary pages. Style-guide pages, block catalogs, layout sandboxes, anything you built for your own reference.
How to check: Pages → All Pages, review anything the client never asked for.
2. Launch settings
Search engine visibility (the noindex trap). This one has two layers, and the second one almost got me. The obvious layer is Settings → Reading → "Discourage search engines from indexing this site". Staging environments have it on, but production must not. The sneaky layer is your SEO plugin: on one site, the Reading setting was fine, but a noindex rule was still sitting in the SEO plugin's configuration from the staging days. Weeks of indexing time are lost this way, silently.
How to check: Verify the Reading setting, then open your SEO plugin's settings and check its index rules. Finally, view the page source of the live homepage and search for noindex in the <meta name="robots"> tag. That's the ground truth.
WP_DEBUG. Debug mode on a production site can print warnings, with file paths, right onto the page for every visitor.
How to check: Open wp-config.php and confirm WP_DEBUG is false.
Admin email. If the site's admin address is still yours, the client's password resets and system notices go to you forever.
How to check: Settings → General → Administration Email Address.
Permalinks / rewrite rules. After a migration, stale rewrite rules are a classic source of unexplained 404s.
How to check: Settings → Permalinks → Save Changes (yes, just re-saving flushes the rules), then click through a few posts and archive pages.
3. Security loose ends
Four small things that take five minutes total and are exactly the kind of leftovers a security scan (or a curious visitor) finds later:
-
File editor:
DISALLOW_FILE_EDITinwp-config.phpdisables the built-in theme/plugin code editor. A client account clicking around in there is a risk nobody needs. - XML-RPC: if nothing uses it (Jetpack, some mobile apps), it's an open door for brute-force amplification. Disable it via filter or plugin.
-
debug.log: a
wp-content/debug.logfile left web-accessible is a quiet information leak. Delete it and confirm logging is off. -
The 'admin' username: a default
adminaccount is half of a credential-stuffing attempt already solved. Rename or replace it.
4. Site health before delivery
Outdated plugins. Taking over or delivering a site with plugins that haven't been updated on WordPress.org in over a year means handing the client a maintenance liability without telling them.
How to check: For each installed plugin, including inactive ones, check its "Last updated" date on its WordPress.org page. Flag anything past 6 months; treat anything past a year as a conversation you need to have with the client before handoff, not after.
Inactive plugins. They still ship code. If it's not needed, it shouldn't ship.
How to check: Plugins → Inactive, and delete what has no reason to stay.
5. Beyond the basics
Depending on the hosting stack, a few more things deserve a look. These are harder to automate, which is exactly why you want the basics above done quickly and reliably:
- Cache purge after the final content change. A page cache that never got purged will serve the old price, the old phone number, the old everything, with zero errors logged.
- Leftover staging credentials. Test admin accounts and staging logins have a talent for surviving into production.
- Hardcoded dev URLs in the database. My opening story. A search-replace pass over the database (with a proper serialized-data-aware tool) before launch would have saved us an afternoon of page-by-page hunting, and a permanent line in an incident log. How to check: Don't trust the search-replace tool alone. Click through the primary navigation, footer links, and CTA buttons on the live site, and open a few image-heavy pages, right after migration.
6. The missing step: prove what you checked
Here's the part almost no checklist talks about.
Running the checks protects the site. Showing the checks protects the relationship. A client can't see the noindex flag you flipped back or the debug log you deleted. To them, a clean launch and a lucky launch look identical. The difference only becomes visible when something breaks.
So make the invisible work visible. Before handoff, write a short plain-text delivery note:
Pre-launch verification - example.com - 2026-07-02
✓ Test content removed (posts, pages, media)
✓ Search engine indexing enabled (Reading settings + SEO plugin + meta verified)
✓ WP_DEBUG disabled
✓ Admin email set to client
✓ File editor locked, XML-RPC disabled, no debug.log present
✓ Default 'admin' username: not present
✓ Plugin update status reviewed (2 flagged, listed below)
Attach it to your delivery email. It takes ten minutes, it reads as professionalism, and months later, when someone asks "was this checked?", you have an answer with a date on it.
7. The checklist (copy-paste version)
## Content cleanup
- [ ] Test posts/pages deleted (incl. custom post types & trash)
- [ ] Unused media removed (placeholders, duplicates, watermarked images)
- [ ] Temporary/reference pages removed
## Launch settings
- [ ] Reading settings: search engine indexing allowed
- [ ] SEO plugin: no leftover noindex rules
- [ ] Live page source: no unexpected noindex meta tag
- [ ] WP_DEBUG = false
- [ ] Admin email = client's address
- [ ] Permalinks re-saved (rewrite rules flushed)
## Security
- [ ] DISALLOW_FILE_EDIT set
- [ ] XML-RPC disabled (if unused)
- [ ] debug.log deleted, logging off
- [ ] No default 'admin' username
## Site health
- [ ] All plugins (incl. inactive) checked for last-updated date
- [ ] Unneeded inactive plugins deleted
## Beyond the basics
- [ ] Cache purged after final changes
- [ ] Staging/test credentials removed
- [ ] Database search-replace for dev URLs done
- [ ] Site clicked through (nav, footer, CTAs, image-heavy pages): no broken links or images
## Prove it
- [ ] Plain-text delivery note written and attached
Prefer clicking checkboxes over copy-pasting markdown? Here's the same 25 items as an interactive web checklist you can walk through in your browser.
One more thing
You can run this whole list manually. Copy the markdown above into your project notes and it's yours.
I'll be honest about why I wrote this: I kept making these mistakes myself, so I also built a free WordPress plugin called Noshi-Kanamer that automates a good chunk of this list: it detects leftover test content, noindex (including SEO-plugin and code-level rules), WP_DEBUG, debug.log, the default admin username and more, then generates a plain-text handoff report you can paste straight into your delivery email. The checklist above works fine without it. The plugin just makes the boring parts fast.
Either way, check before you hand over the keys, and leave a note that proves you did.
Want this as an interactive checklist you can walk through step by step? I turned this list into a free web checklist with all 25 items in one place, and a peek at what's coming next: an AI Site Safety Report for client handoff, now taking early access signups.

Top comments (5)
One thing that always makes me wince a little during a client handoff, regardless of the platform, is the moment you realize you're handing over the keys to something they might accidentally break or neglect. For SaaS, we control the infrastructure, which simplifies ongoing maintenance and security, but for a client-managed site, that's an entirely different beast where the long-term health depends so much on their practices.
We spend a lot of time on observability and alerting for our own platforms, and I've found it's crucial to bake in at least a basic version of that for client sites too. Beyond just ensuring the site is performant at launch, setting up simple uptime monitoring and perhaps a few key performance indicators (KPIs) through something like Google Analytics, even if it's just tracking page load times for critical paths, can be a lifesaver. It helps them see issues before they become emergencies, and it gives you a data-driven way to prove stability and performance post-handoff.
And the "cleanup" phase isn't just for launch; it's an ongoing process. Thinking about how the client will maintain that clean state – whether it's through scheduled plugin updates, routine security scans, or just content management best practices – needs to be an explicit part of the handoff conversation. If they don't have a clear roadmap for keeping the site patched and performant, all that meticulous pre-launch work can quickly unravel, which inevitably circles back to you. It's less about "what to check" at launch and more about "how to sustain" that state long-term.
Totally agree — the site belongs to the client, so its long-term health really does depend on how they maintain it day to day. That's a real risk, and I don't think a one-time checklist can fully solve it.
That said, this piece was scoped more narrowly: the moment the builder steps back and hands the keys over. What I wanted to collect was the essential list to send along at that exact moment, so the client has something to trust.
The "prove it" section at the end is really aimed at that — not ongoing monitoring, but a dated snapshot the client can point to later. Your point about baking in observability for the long term is a great follow-up angle, thanks for adding it.🙌
Nice article, it raises a lot of important points.
I handle WP debug.log files differently than most advise. In my opinion, I'd rather have the info in that log file available to me in the event that something crashes, or even just misbehaves a little, in production. If you don't have it, well then you have to set up a test case and replicate that crash, whether in production or test.
I do two things to make this manageable. First, your wp-config.php configuration has to evolve a little. This is what I put in there:
define( 'WP_DEBUG', true );define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
That causes the error logging to go into the wp-content/debug.log file, but not be displayed on the screen.
Now, to prevent people from harvesting that debug.log data, I make a webserver configuration change. In nginx, it looks like this:
if ( $request_uri ~* "\.log$" ) {return 403;
}
That prevents any log files, defined as a filename ending in "
.log", from being accessed. You can do something very similar for Apache servers using an .htaccess configuration statement.To address the ever-growing-logfile concern, I like the way Kinsta handles it: use
logrotateto rotate debug.log just like every other logfile on the system. Set it up to rotate every day and your logfile never gets too big. If you are going to have logrotate keep several generations of debug.log, tweak the webserver configuration so it rejects access to any of the various logfile names (likedebug.log.1,debug.log.2.gzand so on).Really appreciate the detailed breakdown — using logrotate the way Kinsta does is a nice touch I hadn't spelled out.
I think we're agreeing on the same principle from different angles: the real risk isn't debug.log existing, it's debug.log being web-accessible.
My checklist defaults to "delete it" because it's the fastest zero-config fix for someone who hasn't set up log rotation or a webserver rule yet. But if you've already got the 403 block and logrotate in place like you described, keeping WP_DEBUG_LOG on and mining that history is strictly better than deleting it blind.
Might be worth adding as an "if you've set this up properly" alternative next time I revisit the piece. Thanks for adding the nuance!🙌
Hi tienbuilds, I saw your post about the WordPress pre-launch checklist and thought of Clypify, a tool that can help you streamline your content workflow and automate publishing to WordPress. With Clypify, you can focus on creating high-quality content without worrying about the logistics. Free plan at clypify.com — no card needed.