Skip to content

Macros

asRegion

Mark any imported component as a region, whether it is a named import, a default import or a barrel re-export. It covers the imports the `with { … }` attribute form cannot reach, and works the same in .svelte, .ts and .js.

On this page

The usual way to mark a region is with an import attribute:

import Counter from './Counter.svelte' with { wake: 'visible' };

An import attribute only works on a default import of one file, though. Sometimes the only way to reach a component is through a barrel, such as a design system’s index.ts or a @company/ui package, where it arrives as a named import and there is nowhere to put the with { … }:

import { Header, Footer } from '@company/ui'; // named — no `with { … }` possible

import.meta.og.asRegion(Comp, options) handles that case by marking any imported component (named, default, or from a barrel) as a region:

<script>
  import { Header } from '@company/ui';
  const HeaderIsland = import.meta.og.asRegion(Header, { wake: 'load' });
</script>

<HeaderIsland {...props} />

The options are exactly with { … }

options is an object that accepts exactly what an import attribute accepts, no more and no less, because both go through the same parser and so cannot drift apart. Every mode works:

const HeaderIsland = import.meta.og.asRegion(Header, { wake: 'load' });                     // placed island
const ChartHole    = import.meta.og.asRegion(Chart, { render: 'deferred', fetch: 'visible' }); // server hole
const BlockRaw     = import.meta.og.asRegion(Block, { region: 'raw' });                       // held → region(BlockRaw, …)

The output is also identical to the with { … } form, except that the generated entry imports the component by its export name, so region identity is keyed on source#exportName. Two named exports from one barrel are therefore two distinct regions and never collide.

Tree-shaking is preserved

A region taken from a large mixed barrel ships only its own component, not the whole barrel. The generated entry does import { Header } from '@company/ui', which the bundler tree-shakes exactly as it would anywhere else, so a 100-component barrel with one region marked pulls in one component.

Works in .svelte, .ts, and .js

The same call produces one of two things, depending on where it lives:

  • In a .svelte host it creates a placed island, which you render inline (<HeaderIsland/>, or <svelte:component this={HeaderIsland}/>).
  • In a .ts / .js registry or remote it creates a held binding, a mountable value that a third-party renderer can place or that region() can turn into a held region:
import { Header } from '@company/ui';

// a mountable held binding — Builder.io's <svelte:component> places it directly,
// and region() can still cross it over the wire
const HeaderRegion = import.meta.og.asRegion(Header, { wake: 'visible' });

export const registry = [{ name: 'header', component: HeaderRegion }];

This one line is what turns a component imported from a barrel into something a CMS or page builder can render. Mountable .ts bindings describes what such a binding can do.

The rules

  • Top-level const only. Write const Local = import.meta.og.asRegion(Comp, options), one binding per statement, at the top level of the module or <script>. It compiles to a hoisted import, so it can never appear inside a loop, function, block, larger expression, <script module> or markup, and each of those is a build error.
  • The first argument is a component you imported: a bare identifier bound to a top-level import (named or default, but not import * as).
  • options is an object literal. There is no string shorthand; write a { wake: 'load' } object, as you would in a with { … } clause.
  • One mechanism per component. A component already marked with an import attribute cannot also be passed to asRegion, so pick one.

Misuse fails the build with an [ogygia] message that names the file and the fix. asRegion is a compile-time construct that is rewritten to a hoisted binding import, so it does not exist at runtime.