---
sourceDocument: Brazil Build or modify applications
sourceDocumentLink: https://www.servicenow.com/docs/r/application-development

 Release :

    - brazil

ft:locale :

    - en-US

ft:publication_title :

    - Brazil Build or modify applications

ft:clusterId :

    - cadev

bundleId :

    - cadev

workflow :

    - Development, Data, and Analytics


---

# Regions and the wrapper contract

# Regions and the wrapper contract {#ariaid-title1}

Release version: Brazil  
Updated September 29, 2026  
![](https://www.servicenow.com/docs/portal-asset/ico-clock) 4 minutes to read  
A config admin can restructure a page's layout directly on the rendered page and persist the result as an admin override. Config admins can add and remove rows, columns, and widgets, resize column spans, change scrolling, and
move containers.

A region is a named, addressable area of a page. A region is authored in code with the `region` template and rendered inside a wrapper element that contains the region. The preceding topics in this series cover admin overrides for property values. This topic covers admin overrides for layouts, including how to edit an already-rendered region and the persistence path that makes an edit stick.

## Region wrapper contract {#regions-and-the-wrapper-contract__regions-and-the-wrapper-contract-region-wrapper-contract}

Every rendered region is enclosed in exactly one wrapper element. The wrapper is part of the rendered-output contract and uses a specific data attribute for identification.

A region's name is the thing an override is keyed on.

## Region spacing {#regions-and-the-wrapper-contract__regions-and-the-wrapper-contract-region-spacing}

A region's spacing is not something the editor exposes. The runtime emits one uniform gutter between all widgets and no padding. Spacing is retuned through the `--layout-gap` custom property, or `--spacing-layout` for one subtree, rather than through the DSL. The paddings-and-gaps popover that used to write `gap` and `padding` is gone with them.

`gap` and `padding` are deprecated on the authoring side too. Both are still parsed and consumed by the region, so they never reach the rendered element. But they are ignored on any tag, with any value, and warned once per attribute and tag pair. They existed to tune spacing per container, which is exactly what a uniform gutter cannot allow. A `padding` on a column, or a smaller `gap` on a nested row, doubles or breaks the gutter at that nesting boundary. `margin` was considered for the same purpose and deliberately left out.

## Which element owns a region {#regions-and-the-wrapper-contract__regions-and-the-wrapper-contract-which-element-owns-a-region}

One element per page owns its regions, and which one depends on the kind of page.
{#regions-and-the-wrapper-contract__table-regions-and-the-wrapper-contract-which-element-owns-a-region__entry__3}

| Page | Region owner | Row keyed on |
|-|-|-|
| A normal custom page (anything an app author wrote) | The page widget, and nothing else | The page's widget record, read from the manifest with no round trip |
| A core-ui page (a list page or a record page) | The view widget, and never the page | That widget's `sys_aix_widget` row, read from the instance |
[ ]

{#regions-and-the-wrapper-contract__table-regions-and-the-wrapper-contract-which-element-owns-a-region}

The page is the outermost tag in the region's custom-element ancestor chain that the client manifest carries a widget record for. Layouts and app-level lifecycle modules aren't in that set, so they are skipped without a test
of their own.

Two consequences follow:

* A normal page's child widgets are not searched for regions. A region is the page's own layout. A widget that renders one is describing a layout it does not own. An override keyed on the page would claim the page owns something its child authored. Such a region is refused rather than reassigned upward; no session, nothing to save; and the widget entries inside it are untouched.
* On a core-ui page, being the page widget is not enough. The page itself is platform chrome nobody configures. The page body is a view widget resolved per request. That widget is what an admin is rearranging, so it is the only element on the page allowed to own a region. Several views can be configured and only the one the platform's view-rule engine picked is on the page, so the DOM settles which one it was.

## The printer {#regions-and-the-wrapper-contract__regions-and-the-wrapper-contract-round-trip-to-storable-text}

The printer converts an edited tree to storable text. Before it returns the text, it verifies its own output. The printer splits, decodes, and re-parses the text it printed. It then compares the two trees. If the trees do not
match, the printer throws an error.

This behavior is necessary, not cautious. The renderer catches render errors and falls back to the code-authored template without warning. A mis-printed edit does not cause an error. It causes an edit that appears to do
nothing. The printer throws an error at the print step to prevent this.

## What the printer rejects {#regions-and-the-wrapper-contract__regions-and-the-wrapper-contract-what-the-printer-rejects}

The printer rejects these three items:

* Object-valued interpolations
* Strings that contain `}`
* `<raw>` blocks

The platform save-time splitter treats the first `}` after a `${` as the end of an interpolation. This is why the printer rejects object-valued interpolations and strings that contain
`}`. An admin can trigger the second condition by typing an ordinary label.

Stored DSL rejects `<raw>` blocks as a cross-site scripting risk. A region that contains a `<raw>` block is not editable.

## Unstored regions {#regions-and-the-wrapper-contract__regions-and-the-wrapper-contract-unstored-regions}

Unstored regions are editable. Override rows exist only for regions that an admin has already overridden. A region that has never been modified has no row.

The renderer records the code-authored tree it walked. This gives the editor a starting point when no stored row exists. Under server-side rendering, this recording does nothing. This is correct because the editor runs
client-side.

## The deprecated \<stack\> tag {#regions-and-the-wrapper-contract__regions-and-the-wrapper-contract-deprecated-stack-tag}

The deprecated `<stack>` tag does not reach the editor. Both editor inputs go through the same parser. The parser rewrites every `<stack>` tag before validation runs. It converts each
`<stack>` into a `row` that holds one full-width `column`. The parser drops all attributes on the `<stack>` tag and writes a named console warning
for each one. The first time an admin saves a region that contained a `<stack>` tag, the stored text uses rows and columns.
**Related concepts**   

* [Editing and persisting layouts](https://www.servicenow.com/docs/gv2t8lCX0R8VBktwQNOBDQ "Configuration mode unlocks every region on a page. Each region edits and saves independently. Learn about layout ownership, persistence, and editor limitations.")
* [Placing Lux widgets in regions](https://www.servicenow.com/docs/TstBLstGI86~3Bq8sjXQWA "A seam is a placement point in a region, the edge of a widget or the gap between two widgets. Use seams to add widgets from the toolbox and configure widgets placed inside a region.")
* [Layouts and editable regions](https://www.servicenow.com/docs/gCeLfOK4anb959o8jYDalA "A layout wraps every page in your app's chrome (header, sidebar, footer) while pages render only their own content. Within a page, a region composes widgets into a structured arrangement that a visual editor can rearrange later.")
* [Configuration model](https://www.servicenow.com/docs/GMie8eKbnJlCpmbXGwkzcw "Lux makes a component's behavior configurable at three levels: code, admin policy, and individual preference without three separate systems to learn. You add one decorator, @config, to a class field to opt a property into all of it.")  
**Related reference**   

* [Configurable properties for Lux experiences](https://www.servicenow.com/docs/Z8ch9vNd7cy1kj11~SRK2A "A property becomes configurable and visible in the props pane when you add a decorator to it. The decorator's options set the field type that the props pane renders, and also set the storage key that the resolved value is read back from.")  
**Related topics**   

* admin-experience.html

