First render
Everything you need to render your first JSX to an HTML string.
Hello world#
renderToString always returns a Promise<string>, even for synchronous
trees. The string is ready to send over HTTP or write to a file.
import { renderToString } from "@vincle/core";
const html = await renderToString( <html lang="en"> <head> <title>Hello, world!</title> </head> <body> <h1>Hello, world!</h1> </body> </html>,);<html lang="en"> <head> <title>Hello, world!</title> </head> <body> <h1>Hello, world!</h1> </body></html>Components are functions#
A component is a plain function: props in, JSX out. No classes, no hooks, no
lifecycle. Children arrive in the children prop.
import { renderToString, type JSX } from "@vincle/core";
function Layout({ title, children }: { title: string; children: JSX.Element | JSX.Element[] }) { return ( <html lang="en"> <head> <title>{title}</title> </head> <body>{children}</body> </html> );}
const html = await renderToString( <Layout title="My page"> <h1>Welcome</h1> <p>This is a page rendered with Vincle.</p> </Layout>,);Same props, same output: components are easy to test and cache.
Values are escaped#
Every value is escaped for where it lands. raw() is the only way to emit
markup, for HTML you trust.
import { renderToString, raw } from "@vincle/core";
// User input is HTML-escaped automaticallyconst userInput = '<script>alert("xss")</script>';const html = await renderToString(<p>{userInput}</p>);
// Use raw() only for trusted HTML you generated yourselfconst trustedHtml = "<em>rendered from your own markdown</em>";const html2 = await renderToString(<article>{raw(trustedHtml)}</article>);<p><script>alert("xss")</script></p><article><em>rendered from your own markdown</em></article>See the security model.
Async works directly#
Any component can be an async function. renderToString awaits the whole
tree, so the component that needs data is the component that fetches it.
import { renderToString } from "@vincle/core";
declare const db: { users: { findById(id: string): Promise<{ name: string; email: string }>; };};
async function UserCard({ id }: { id: string }) { const user = await db.users.findById(id); return ( <div class="card"> <h2>{user.name}</h2> <p>{user.email}</p> </div> );}
const html = await renderToString(<UserCard id="42" />);Where to next#
- Elements & attributes:
class,style, booleans - Components: props, composition, async
- Load data in your components:
awaitinside render