Skip to main content

Layout

Layout in Backroad is done with container methods: br.columns, br.tabs, br.collapse, br.sidebar, br.bottom. Each returns a manager (or an array of them) scoped to the new container, and any subsequent component calls happen inside that scope.

For the full container model, see Fundamentals: Containers.

Columns

const [left, right] = br.columns({ columns: 2 });
left.write({ body: '## Left' });
right.write({ body: '## Right' });

Pass ratios for uneven columns:

const [narrow, wide] = br.columns({ columns: [1, 3] }); // 25 / 75

Tabs

const [a, b] = br.tabs({ labels: ['Overview', 'Details'] });
a.write({ body: 'Overview content' });
b.write({ body: 'Details content' });

Collapse

const advanced = br.collapse({ label: 'Advanced options' });
advanced.toggle({ label: 'Verbose mode' });
advanced.numberInput({ label: 'Retries', defaultValue: 3 });
const sidebar = br.sidebar({});
sidebar.write({ body: '## Filters' });
sidebar.select({
label: 'Region',
options: [
{ value: 'eu', label: 'EU' },
{ value: 'us', label: 'US' },
],
});

Bottom (dock)

br.bottom() pins its children to the bottom of the page while everything above scrolls — ideal for a chat input that should stay put as the conversation grows.

const message = br.bottom().chatInput({ id: 'chat' });
if (message) {
// handle the submitted message
}

The dock lives outside the scrolling body, so its position doesn't depend on when you emit it — render it wherever is convenient in your script and it still sits at the bottom. See LLM components for the full chat pattern.

Nesting

Containers nest freely:

const [left, right] = br.columns({ columns: 2 });

const [topA, topB] = left.tabs({ labels: ['A', 'B'] });
topA.write({ body: 'Tab A inside the left column.' });
topB.write({ body: 'Tab B inside the left column.' });

const moreRight = right.collapse({ label: 'More on the right' });
moreRight.write({ body: 'Hidden content.' });

Try it