Search
Code1,917
Versions 0-17 of this val were done with Hono and server-rendering.Versions 18+ were generated with Townie and use client-side React.
Versions 0-17 of this val were done with Hono and server-rendering.Versions 18+ were generated with Townie and use client-side React.
/** @jsxImportSource https://esm.sh/react */import React, { useState, useEffect } from "https://esm.sh/react";import { createRoot } from "https://esm.sh/react-dom/client";function client() { createRoot(document.getElementById("root")).render(<App />);}if (typeof document !== "undefined") { client(); }Versions 0-17 of this val were done with Hono and server-rendering.Versions 18+ were generated with Townie and use client-side React.
Versions 0-17 of this val were done with Hono and server-rendering.Versions 18+ were generated with Townie and use client-side React.
/** @jsxImportSource https://esm.sh/react */import confetti from "https://esm.sh/canvas-confetti";import React, { useEffect, useState } from "https://esm.sh/react";import { createRoot } from "https://esm.sh/react-dom/client"; <h2 className="font-bold mb-4">Stripe Test Mode Instructions</h2> <ol className="list-decimal list-inside space-y-1 text-sm"> <li>Use card number: 4242 4242 4242 4242</li>function client() { const root = document.getElementById("root");}if (typeof document !== "undefined") { client(); }# SSR React Mini & SQLite Todo AppThis Todo App is server rendered *and* client-hydrated React. This architecture is a lightweight alternative to NextJS, RemixJS, or other React metaframeworks with no compile or build step. The data is saved server-side in [Val Town SQLite](https://docs.val.town/std/sqlite/).## SSR React Mini FrameworkThis ["framework"](https://www.val.town/v/stevekrouse/ssr_react_mini) is currently 44 lines of code, so it's obviously not a true replacement for NextJS or Remix.The trick is [client-side importing](https://www.val.town/v/stevekrouse/ssr_react_mini?v=53#L30) the React component that you're [server rendering](https://www.val.town/v/stevekrouse/ssr_react_mini?v=53#L35-37). Val Town is uniquely suited for this trick because it both runs your code server-side and exposes vals as [modules](https://esm.town/v/stevekrouse/TodoApp) importable by the browser.The tricky part is making sure that server-only code doesn't run on the client and vice-versa. For example, because this val colocates the server-side `loader` and `action` with the React component we have to be careful to do all server-only imports (ie sqlite) dynamically inside the [`loader`](https://www.val.town/v/stevekrouse/TodoApp?v=246#L7) and [`action`](https://www.val.town/v/stevekrouse/TodoApp?v=246#L20), so they only run server-side.Shows how to get a JSON object containing a base64 imaged stored in Val Town blob storage and render it as an image in the DOM with React. - The client-side React component makes a fetch request to "/image". - This request is handled by our server function.2. Server-side handling: - We receive this Response object from `blob.getJSON()`. - We don't need to extract the data on the server side. - We can directly return this Response object to the client.4. Sending the response to the client: - We set the appropriate "Content-Type" header (e.g., "application/json"). - We return the Response object to the client.5. Client-side handling: - The fetch request in the React component receives the Response. - We call `response.json()` to parse the JSON object from the Response.7. Updating the React state:Shows how to get a Val Town blob and render it as an image in the DOM with React. - The client-side React component makes a fetch request to "/image". - This request is handled by our server function.2. Server-side handling: - We receive this Response object from `blob.get()`. - We don't need to extract the data on the server side. - We can directly return this Response object to the client.4. Sending the response to the client: - We set the appropriate "Content-Type" header (e.g., "image/png"). - We return the Response object to the client.5. Client-side handling: - The fetch request in the React component receives the Response. - We call `response.blob()` to get a Blob object from the Response.7. Updating the React state:// This approach creates a PC application with a left-side menu structure as requested.// We'll use React for the UI components and React Router for navigation.// The server will serve the HTML, and the client-side React application will handle the menu and routing./** @jsxImportSource https://esm.sh/react */import ReactDOM from "https://esm.sh/react-dom@18.2.0";import { BrowserRouter, Link, Route, Routes } from "https://esm.sh/react-router-dom@6.11.2";import React from "https://esm.sh/react@18.2.0";function MenuItem({ item }) { const [isOpen, setIsOpen] = React.useState(false); const [isHovered, setIsHovered] = React.useState(false);function client() { ReactDOM.createRoot(document.getElementById("root")).render(<App />);}if (typeof document !== "undefined") { client(); }/** @jsxImportSource https://esm.sh/react */import React from "https://esm.sh/react";import { renderToString } from "https://esm.sh/react-dom/server";import { createRoot } from "https://esm.sh/react-dom/client";// Client-side App componentfunction App({ data }) {// Client-side renderingfunction client() { fetch('/api/health-data')if (typeof document !== "undefined") { client();}# SSR React Mini & SQLite Todo AppThis Todo App is server rendered *and* client-hydrated React. This architecture is a lightweight alternative to NextJS, RemixJS, or other React metaframeworks with no compile or build step. The data is saved server-side in [Val Town SQLite](https://docs.val.town/std/sqlite/).## SSR React Mini FrameworkThis ["framework"](https://www.val.town/v/stevekrouse/ssr_react_mini) is currently 44 lines of code, so it's obviously not a true replacement for NextJS or Remix.The trick is [client-side importing](https://www.val.town/v/stevekrouse/ssr_react_mini?v=53#L30) the React component that you're [server rendering](https://www.val.town/v/stevekrouse/ssr_react_mini?v=53#L35-37). Val Town is uniquely suited for this trick because it both runs your code server-side and exposes vals as [modules](https://esm.town/v/stevekrouse/TodoApp) importable by the browser.The tricky part is making sure that server-only code doesn't run on the client and vice-versa. For example, because this val colocates the server-side `loader` and `action` with the React component we have to be careful to do all server-only imports (ie sqlite) dynamically inside the [`loader`](https://www.val.town/v/stevekrouse/TodoApp?v=246#L7) and [`action`](https://www.val.town/v/stevekrouse/TodoApp?v=246#L20), so they only run server-side.// Interactive forestry financial model simulator.// It will use React for the UI, recharts for data visualization, and custom slider components.// The server will render the initial HTML, and the client-side JavaScript will handle the interactivity./** @jsxImportSource https://esm.sh/react */import React, { useState } from "https://esm.sh/react";import { createRoot } from "https://esm.sh/react-dom/client";import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from "https://esm.sh/recharts"; <CartesianGrid strokeDasharray="3 3" /> <XAxis dataKey="year" label={{ value: 'Year', position: 'insideBottom', offset: -5 }} /> <YAxis label={{ value: 'Amount ($)', angle: -90, position: 'insideLeft' }} /> <Tooltip />function client() { createRoot(document.getElementById("root")).render(<App />);if (typeof document !== "undefined") { client();}// This approach creates a simple React component that embeds the MicroReact widget// and allows for customization of its parameters. The component will be rendered// on the client-side, and the server will return the HTML structure with the// necessary scripts./** @jsxImportSource https://esm.sh/react */import React from "https://esm.sh/react";import { createRoot } from "https://esm.sh/react-dom/client";interface MicroReactProps { id: string; reactions?: string; allowMultiple?: boolean;function MicroReact({ id, reactions = "12345", allowMultiple = false, api_base,}: MicroReactProps) { const baseUrl = "https://microreact.glitch.me/embed/index.html"; const params = new URLSearchParams({ id, reactions, allowMultiple: allowMultiple ? "1" : "0", loading="lazy" title="Leave a reaction" /> <div> <h1>MicroReact Demo</h1> <MicroReact id="demo-page" /> <p>This is a demo of the MicroReact widget. You can customize it by passing different props to the MicroReact component.</p> <h2>Customized MicroReact</h2> <MicroReact id="custom-demo" reactions="123" allowMultiple={true}function client() { createRoot(document.getElementById("root")).render(<App />);if (typeof document !== "undefined") { client();} <head> <title>MicroReact Demo</title> <style>${css}</style>// parse it using cheerio, extract the required information,// and render it in a table format. We'll use React for the client-side rendering./** @jsxImportSource https://esm.sh/react */import React, { useState, useEffect } from "https://esm.sh/react";import { createRoot } from "https://esm.sh/react-dom/client";function client() { createRoot(document.getElementById("root")).render(<App />);if (typeof document !== "undefined") { client(); }