Server rendering and hydration
The elements are markup on the server and upgrade in the browser. A server-rendered page carries
the tags with their attributes and a plain <input> inside the field. The page works as a plain
form until the elements upgrade.
The server entry
Section titled “The server entry”A server bundle resolves the package to its server entry,
which imports without a DOM. The call to defineTelixonElements() belongs in the client entry of
the application.
What the server renders
Section titled “What the server renders”The React example renders its component to a string and writes the markup into the page:
import { renderToString } from 'react-dom/server';import { App } from './App';
export function render(): string { return renderToString(<App />);}// Writes the server-rendered React markup into the built page, which the static server then serves as is.import { readFileSync, writeFileSync } from 'node:fs';
const { render } = await import('../dist/server/entry-server.js');const page = new URL('../dist/client/react/index.html', import.meta.url);writeFileSync( page, readFileSync(page, 'utf8').replace('<!--app-html-->', () => render()),);The field in that page renders as its tags, their attributes, and the input:
<telixon-phone-field name="phone" default-region="US" calling-code-in-input="false" auto-placeholder="" required=""> <telixon-region-picker></telixon-region-picker> <input id="phone-input" type="tel" autocomplete="tel" /></telixon-phone-field>The picker renders empty. Its trigger, popup, search field, and listbox are built on the client inside a shadow root, which a hydrating framework never compares with its own markup. The flag paints itself through a pseudo-element and adds no children either.
The upgrade
Section titled “The upgrade”Once the client entry defines the elements, each one upgrades in place. The field finds its input,
loads the engine, and attaches the widget. Until the engine has loaded, the element carries the
engine-loading state and the input takes keystrokes as a plain input. Text typed before that moment
is read once the widget attaches, which keeps a number typed before hydration in the form.
React 19 sets attributes only while it hydrates. It adds no properties and no custom event listeners then, which is why the React example passes the configuration as attributes and listens from an effect, as the frameworks guide shows.