How to Prepare Content for a White Label App
Builds stall on missing strings and mis-cropped images far more often than they stall on code, so treat the content inventory as a delivery dependency with its own deadline.
Most delays on a 30 to 60 day white-label build are not engineering delays. They are content delays. The screens are built, the Firestore collections are wired, Stripe passes in test mode, and then the project sits for eleven days because nobody has written the refund policy, nobody can find a transparent PNG of the logo, and the App Store listing needs a support URL that does not exist yet.
Content is a dependency with its own deadline. Here is the inventory a white-label app actually consumes, roughly in the order the build needs it.
The copy deck: one row per string, not a prose document
A Word document does not survive contact with a Flutter codebase. What a developer needs is a flat sheet where every row is one string with a stable key. Workable columns: key, screen, English text, character limit, notes.
Character limits matter more than people expect. On a 375pt-wide screen, a filled button with 16px semibold text starts wrapping around 22 characters. A list tile subtitle truncates near 40. If the deck says 'Book Your Appointment Now' for a button, someone will spot the wrap during device testing and shorten it without telling anyone, and from then on the deck and the app disagree.
Count the strings before you start. A modest catalog or booking app runs 180 to 300 distinct strings once errors and empty states are included. Most owners write about 60 and assume the rest will appear. The other 200 get written by a developer at 11pm, which is how one app ends up saying 'Something went wrong' four different ways.
Image specs, and the assets that get requested most
Flutter renders at 1x, 2x and 3x. Supplying one 800px JPEG of a product means it will look soft on any recent phone. Send the largest original you have and let the build downscale.
| Asset | Ratio | Minimum size | Format |
|---|---|---|---|
| App icon | 1:1 | 1024 x 1024, no transparency, square corners | PNG |
| In-app logo | free | 3x display height, transparent | PNG or SVG |
| Catalog item | 4:3 or 1:1, pick one | 1200px long edge | JPEG |
| Hero banner | 16:9 | 1920 x 1080 | JPEG |
| Headshot | 1:1, face centred | 600 x 600 | JPEG |
| Store screenshots | 19.5:9 iPhone | 1290 x 2796 | PNG |
The most common failure is mixed aspect ratios inside one catalog. Half the items are square studio shots, half are landscape phone photos, and the grid looks broken no matter which BoxFit is used. Choose one ratio, crop everything to it before handover, and keep a safe area, since anything within roughly 8% of an edge can be clipped on small screens. Decide the fallback tile too, because every catalog eventually holds an item with no photo.
Legal and store pages that gate submission
Apple and Google both block review over missing pages, and these are pure content:
- A privacy policy at a public HTTPS URL, naming the data you collect. It has to match the answers in App Store Connect privacy questions and the Play Data safety form. Mismatch is a routine rejection.
- Terms of service, with refund and cancellation terms if you take payment.
- A support URL and a monitored support address. A Gmail address is fine; an unmonitored one is not.
- An account deletion path. Play requires an in-app deletion route plus a web-accessible deletion request for apps with accounts, and Apple requires the in-app route. One screen, one paragraph of copy, missed constantly.
- Subscription disclosure shown before purchase: price, period, renewal behaviour, and how to cancel.
Empty states, errors, and the screens nobody writes
Every list has a zero-data version, and on launch day that is exactly what the first users see. A booking app needs copy for no upcoming appointments, no past appointments, no saved card, no search results, no network, and a server error. Six strings for one feature area.
Write errors in two parts: what happened, and what to do next. 'Payment failed' is half a message. 'That card was declined. Try another card or contact your bank.' is a whole one. Where Stripe returns a decline code, the copy should differ for insufficient_funds versus expired_card, because the user's next action differs.
The no-results state deserves particular attention, since it is where people quit. Echo the search term back and offer a route out: clear filters, browse everything, or message support.
Notification strings need their own sheet
Push copy has constraints nothing else in the app has. iOS shows roughly 40 characters of title and about two lines of body on the lock screen before truncating, and Android collapses to a single line until expanded. Write for the truncated view.
For each notification supply five things: trigger, title, body, deep link destination, and whether it is transactional or promotional. That last column is not bureaucracy. Promotional pushes need their own opt-in and a settings toggle, and folding them into the transactional channel is how an app earns mass notification disablement in week two.
Spell out the variables. 'Your appointment with {staff_name} is at {time} tomorrow' tells the build exactly which fields must exist on the record. Vague copy like 'Reminder about your booking' hides a data requirement that surfaces late and expensively.
Onboarding microcopy and permission priming
An iOS system permission dialog can only be shown once. If someone taps Don't Allow, the only recovery is a trip into Settings, which almost nobody makes. So the screen immediately before the dialog is doing the real work.
For each permission, prepare a one-sentence reason in the user's terms plus the purpose string that ships in Info.plist. 'We use your location to show the nearest branch' is a purpose string. 'Required for app functionality' gets rejected.
For sign-up, write the field labels, helper text, validation messages, and the exact wording of the marketing consent checkbox. Pre-ticked consent is not lawful under GDPR, so the default state matters as much as the words do.
What content-ready actually looks like
A build is ready when the copy sheet is complete including errors and empty states, every image is cropped to its declared ratio at 2x or better, the privacy policy and terms are live at real URLs, the notification sheet lists trigger, copy and deep link for each message, and one named person can approve wording without convening a committee.
Assembling that takes two focused days. Skipping it costs about two weeks in the middle of the build, which is the more expensive option.
White-label Flutter apps, delivered in 30-60 days, from $2,500 - full source code included.
Get started