Ecopages0.2.0-rc.4

Creating Components in Ecopages

Components are reusable UI units composed into Pages and Layouts. The default JSX template uses Ecopages JSX, so these examples use .tsx files and JSX in render.

A component with browser behavior

Declare the styles, browser scripts, and child Components a Component needs. Ecopages uses that declaration to collect assets and preserve Integration ownership.

import { eco } from '@ecopages/core';
import type { JsxRenderable } from '@ecopages/jsx';
import './radiant-counter.css';
 
type RadiantCounterProps = { count: number };
 
export const RadiantCounter = eco.component<RadiantCounterProps, JsxRenderable>({
	dependencies: {
		scripts: [{ src: './radiant-counter.script.ts', lazy: { 'on:interaction': 'mouseenter,focusin' } }],
	},
	render: ({ count }) => (
		<radiant-counter count={count}>
			<button type="button" data-ref="decrement" aria-label="Decrement">-</button>
			<span data-ref="count">{count}</span>
			<button type="button" data-ref="increment" aria-label="Increment">+</button>
		</radiant-counter>
	),
});

Radiant support is enabled by default when you configure ecopagesJsxPlugin(). Its SSR output becomes an island only when the Component brings browser behavior.

Use a component in a Page

Pass route wrappers through layout. Import nested components directly — Ecopages discovers local eco.component() imports automatically.

import { RadiantCounter } from '@/components/radiant-counter';
import { BaseLayout } from '@/layouts/base-layout';
import { eco } from '@ecopages/core';
 
export default eco.page({
	layout: BaseLayout,
	metadata: () => ({
		title: 'Home page',
		description: 'This is the homepage of the website',
	}),
	render: () => (
		<>
			<h1>Ecopages</h1>
			<RadiantCounter count={5} />
		</>
	),
});

Lazy browser scripts

Use a lazy declaration when a script should wait for an interaction or visibility trigger.

dependencies: {
	scripts: [{ src: './search.script.ts', lazy: { 'on:interaction': 'focusin' } }],
}

Ecopages stamps island host attributes on hydratable Component SSR roots so developer tools and client runtimes can discover them.

Related guides