Grouped by symptom, not by module, because the person with the problem does not know which module has it. Each answer lists the causes in the order they usually turn out to be true. The first check for almost everything here is the same: look signed out, in a private window or with curl, because a signed-in admin sees unpublished records, uncached pages and placeholders that visitors never get.
It is not showing up
Twelve things that were changed, saved or uploaded and are not on the page, each with the causes in the order they usually turn out to be true, and the check that tells them apart.
My template change is not appearing on the site
In order: it is not deployed (the commit is not on the branch that deploys to this environment; the environment's deploy log in the admin, and the ?v= hash on asset URLs in the page source, show what is deployed). It is the wrong file: the layout points at a different template path than the one you edited, or a site file with the same name overrides the one you changed (site templates win over the platform's). It is cached: a deploy clears the compiled templates, the page cache and the CDN, so after a deploy this is rarely it, but a change to content, or a template edited in place on a development server, can wait on the page cache; the Clear Cache action exists but is limited to super administrators. Someone else's editor uploaded over it: development servers with upload-on-save editors take the last save from any machine.
curl -s https://dev.example.com/ | grep -o 'app.css?v=[0-9a-f]*' # the deployed commit
git log -1 --format=%h origin/develop # what you think is deployed
My CSS or JS change is not appearing
The site serves the committed build output; a change under src/ ships nothing until it is built and the output committed. Then: the asset URL has no cache-buster, so returning browsers keep the old file (add ?v= with the deploy hash); a script without the nonce is refused by the Content Security Policy, reported in the browser console and nowhere else; a new file type is not in the static-asset allow-list; and the browser's own cache, which a hard reload settles.
My layout does not appear in the picker when I create a page
The layout's controller is not Show Page: a layout with no controller is a component layout and never appears in the page form. Otherwise: it is hidden (hidden layouts leave every picker and the layouts list); it belongs to another site of the account (a site's own layouts and the account-wide ones are offered, not a sibling site's); or it was never created, because the Add-layout screen refuses a template file that is not yet deployed.
My component does not appear in the collection's add menu
The layout area's supported layouts do not include it. That list is the whole control, per layout area, and an empty list means "everything" while a list that names only hidden or other-site layouts offers nothing. Then: the component layout is hidden; or it is registered as a page layout by accident, because a template outside components/ got a controller. Nested collections inside components have their own supported lists.
My template renders but every area is empty
The record's active revision has no layout, so it has no areas at all; a record created through the API without revision.layout looks exactly like this, and the admin shows an empty form. Then: the record uses a different layout than the one you added areas to; the layout area names in the template differ from the layout's (names are case-sensitive); you are reading the blog container instead of the post, or the wrong record in a listing; or an older revision is active and the content is on a newer, inactive one. A getter on the wrong category does not come back empty: getAreaText() on an image area prints an error sentence.
{* development only: what areas does this record actually have? *}
{foreach $page->getLayout()->getAreas() as $area}{debug_vars area=$area->getName() type=$area->getType()->getName()}{/foreach}
{% for area in page.getLayout().getAreas() %}{{ debug_vars(area.getName(), area.getType().getName()) }}{% endfor %}
A new layout area is not showing on the editing form
It is an attribute, so it sits on the Attributes tab (a record), behind the Attributes button (a component) or behind a cog beside its parent field (attached). Then: it is inside a collapsed group; it was added to a different layout than this record's revision uses; the layout was not saved; the form was open before the change and needs reloading; or it is hidden.
A new record does not appear in a listing
It is not published, or its publish date is in the future; signed in, you see it anyway. Then: it is on another site; the listing is filtered (a tag or category route, or a controller filter setting) and the record does not match; it is on page two; the listing page is cached and waits for the next purge (a scheduled publish fires the purge only for pages, blogs, posts, FAQ questions and product descriptions); or a custom entity definition's listing needs the record published and the definition publishable.
A new record does not appear in search
Only these types are ever in site search: pages, blogs, blog posts, FAQ questions, product descriptions, and books with their units and pages. Books joined the list after release 2026.8.1, so a site on that release or an earlier one never shows a book or a book page in search. A custom entity record or a form never appears, however it is set up. A record of those types is indexed only when it is published, its SEO robots setting allows indexing, and a signed-out visitor may read it, so members-only content is never in site search. Indexing runs in the background: seconds on a quiet site, minutes during a reindex or a large import. Still missing after that: it was saved by a background process (an asynchronous job or an import run on the server), which queues no indexing, so save it once in the admin; or it is found by its title but not by its words, because the layout areas holding them are not mapped to a search field. When the index itself is behind, Search › Indices has Reindex for each index; Rebuild empties the index before refilling it, so run that out of hours. The full checklist, with a URL that asks the index for one record, is in why a new record is not findable yet.
A page shows on dev but 404s on production
A deploy moves templates between environments, not content: the page exists on the development copy because someone created it there. Create and publish it on production. Then: it is unpublished on production while you are signed in on dev; a custom URL or a rewrite exists on one environment and not the other; the production hostname reaches a different site; or a slug differs in case.
An image renders as a broken link
The file was deleted or has expired in the file manager (a filename with an expiry date is purged after it). Then: the path has a space or special character that was not URL-encoded; the URL carries resize parameters or a .webp extension on a filename of type file, which cannot be transformed; the file sits under templates/, which is never served; or its extension is not in the static-asset allow-list. An <img> printed from a hand-built path rather than the image object has no fallback when any of these is true.
A menu item is missing for some visitors
Menu elements are publishable: an unpublished element is hidden from visitors and shown to a signed-in admin, so "I can see it and they cannot" is usually this. The element's target does not hide it: an element that points at an unpublished page, or at a page restricted to a group, is still shown, and the visitor who follows it gets a not-found or access-denied page. The other cause is the cache: the menu is rendered differently for signed-in visitors inside a page that is cached, so members get the anonymous copy. A template that changes the menu per visitor must call preventCaching() or render that part separately (member pages and the page cache).
An image area renders nothing even though the author uploaded a file
The author saved a draft, or a version that was not made active, so the public revision has no image. Then: the file went into a file field, or was uploaded with type file, so the image getters return blank; the template reads a different layout area name; the template hides a blank image with isBlank() and the layout area really is empty on the active revision; or the template uses the placeholder getter and the placeholder setting hides it for visitors. Check the revision history and the layout area on the active revision.
Was this page helpful?
Your answer goes to the docs team.