Every WordPress build we hand off eventually gets touched by someone who isn't a developer. If the only way to edit a homepage banner is a raw custom field with a cryptic key like `_hero_txt_2`, that's on us, not the client.
Our default approach now is to register a proper meta box with add_meta_box() instead of exposing the built-in Custom Fields panel, which lists every meta key on the post whether or not it's meant to be edited by a human. It takes maybe twenty extra minutes per project and saves an entire support email later, usually the kind that starts with "I can't find where to change the phone number."
Why the built-in panel doesn't work for clients
The stock Custom Fields metabox is genuinely useful for developers poking at data, but it's a flat list of key/value pairs with no validation, no labels beyond whatever key you typed, and no way to hide fields that are only meant to be set once during setup. Handing that to a client is like handing them a spreadsheet of raw database rows and hoping they only touch the right one.
We started noticing the pattern after the third or fourth site where a client had "helpfully" edited a field they shouldn't have, once overwriting a value a shortcode depended on, which broke a whole page layout until we tracked it down.
What we do instead
- Register a dedicated meta box with a clear title, grouped near the content editor rather than buried in the sidebar.
- Use nonces and check them on save, always, even on a field that feels too trivial to bother.
- Label every field in plain language, not the database key, so "Header Phone Number" instead of `_hdr_ph`.
- Group related fields into one box instead of scattering five of them down the page in five separate boxes.
- Add a short helper text under trickier fields, one line explaining what happens if it's left blank.
Sanitizing on save matters just as much as the display side. We run everything through sanitize_text_field() at minimum, and anything that's supposed to be a URL or an email gets the matching WordPress sanitizer rather than a generic one. It's easy to skip this when you're the only one who's ever going to touch the field, but once a client account gets into the mix, treating every save as untrusted input has already caught a handful of accidental HTML pastes from clients copying content out of Word.
The client side of it
The other half of this, one we underestimated at first, is just labeling things the way a client thinks about them rather than the way a developer does. "Hero Image Caption" reads clearly. "hero_cap" does not, even though functionally they're identical. A five-minute pass renaming keys to sensible labels before handoff has cut down on confused emails more than any amount of documentation we've written.
We've also started adding a short PDF walkthrough with screenshots for the handful of fields a client is actually expected to touch regularly, since not every client reads a training email closely on day one, and having something to point back to when they call two months later saves both sides time.
Small thing, but it's the difference between a client who feels in control of their site and one who calls us every time they want to swap a photo. Worth the extra twenty minutes on every single project from here on.