@gluonjs/core / src / repeat
Function: repeat()
repeat<
Item>(items,key,renderItem):RepeatResult
Renders an iterable with stable key-based identity.
Keys must be non-null strings, numbers, or symbols and unique within one result. Invalid keys throw while the result is created, before render() can mutate the DOM.
Type Parameters
Item
Item
Parameters
items
Iterable<Item>
key
(item, index) => PropertyKey
renderItem
(item, index) => TemplateValue
Returns
Example
Render a collection with stable unique keys so insertions, removals, and moves retain the correct DOM identity:
import {
TemplateResult,
directive,
elementRef,
event,
html,
hydrate,
render,
repeat,
suspendRender,
svg,
unsafeHTML,
unsafeURL,
type DirectiveValue,
type EventBinding,
type RefTarget,
type RepeatResult,
type UnsafeHtmlResult,
type UnsafeUrlResult,
} from '@gluonjs/core';
import { prepareForHydration } from '@gluonjs/ssr';
const products = [{ id: 'lamp', name: 'Orbit Lamp' }, { id: 'tray', name: 'Stack Tray' }];
const rows: RepeatResult = repeat(products, (product) => product.id, (product) => html`<li>${product.name}</li>`);
const click: EventBinding = event(() => console.log('saved'), { once: true });
const buttonRef: RefTarget<HTMLButtonElement> = elementRef<HTMLButtonElement>();
const trustedDescription: UnsafeHtmlResult = unsafeHTML('<strong>In stock</strong>');
const trustedManual: UnsafeUrlResult = unsafeURL('https://example.com/manual.pdf');
const text = directive<readonly [string]>((value) => (part) => part.setValue(value));
const status: DirectiveValue = text('Ready');
const icon = svg`<svg viewBox='0 0 10 10'><circle cx='5' cy='5' r='4'></circle></svg>`;
const template: TemplateResult = html`
<section>${icon}<ul>${rows}</ul>${trustedDescription}
<a href=${trustedManual}>Manual</a>
<button ...=${{ ref: buttonRef }} @click=${click}>${status}</button>
</section>
`;
const clientRoot = document.createElement('div');
render(template, clientRoot);
suspendRender(clientRoot);
render(template, clientRoot);
const prepared = await prepareForHydration(template);
if (!(prepared.value instanceof TemplateResult)) throw new Error('Expected one template root');
const hydrationRoot = document.createElement('div');
hydrationRoot.innerHTML = prepared.html;
const hydration = hydrate(prepared.value, hydrationRoot, { expectedMarkup: prepared.html });
console.log(hydration.retained, rows.items.length, buttonRef.value, trustedDescription.markup, trustedManual.value);