3This 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/).
45
67## SSR React Mini Framework
blob_adminREADME.md1 match
3This is a lightweight Blob Admin interface to view and debug your Blob data.
45
67Use this button to install the val:
6const url = new URL(req.url)
7// console.log("url:", url)
8const isImage = url.pathname.endsWith("/image")
910if (isImage) {
11const imageUrl = "https://charlypoly-httpapiscreenshotpageexample.web.val.run/?url=" + url.origin
12// return Response.redirect(imageUrl, 302)
13const res = await fetch(imageUrl)
14const blob = await res.blob()
15return new Response(blob, { headers: { "Content-Type": "image/png" } })
16}
1720const baseUrl = url.origin
21const homeFrame = {
22image: `/${randomPostfix}/image`,
23aspectRatio: "1:1",
24buttons: [
31<head>
32<title>${title}</title>
33<meta property="og:image" content="${url.origin}/${randomPostfix}/image" />
34<meta property="og:image:width" content="800" />
35<meta property="og:image:height" content="800" />
36<meta name="twitter:card" content="summary_large_image" />
37${frameHtml(homeFrame, baseUrl)}
38<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.10.0/p5.min.js" integrity="sha512-lvddmeF7aHRJwdbJeYThWd5kWSjTrXBzCRF/jYROiHzmhMJ1dEXfGH5Q7ft0yhizXTopAETG03s5ajTflauijA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
fluxImageGeneratormain.tsx22 matches
1// This app uses the fal.ai API to generate images based on user prompts.
2// It features a clean UI with an input field for the prompt and a button to generate the image.
3// The generated image is displayed below the input field.
4// React is used for the UI and the fal.ai serverless client for image generation.
5// The app measures and displays the latency for each image generation.
6// The background features randomly placed pixelart lightning bolts in neon yellow.
717const BOLT_SIZE = 40; // Width and height of each bolt
18const DEFAULT_PROMPT = "green grass landscape with text \"val.town\" is engraved, a townhouse in the background";
19const PLACEHOLDER_IMAGE = "https://fal.media/files/penguin/PysYf1-_ddhM7JKiLrkcF.png";
20const RATE_LIMIT = 15; // requests per hour
21const RATE_LIMIT_WINDOW = 5 * 60 * 1000; // 5 minutes in milliseconds
72function App() {
73const [prompt, setPrompt] = useState(DEFAULT_PROMPT);
74const [imageUrl, setImageUrl] = useState(PLACEHOLDER_IMAGE);
75const [latency, setLatency] = useState<number | null>(null);
76const [loading, setLoading] = useState(false);
77const [error, setError] = useState("");
7879const generateImage = async () => {
80setLoading(true);
81setError("");
87});
88const data = await response.json();
89if (!response.ok) throw new Error(data.error || "Failed to generate image");
90setLatency(data.latency);
91setImageUrl(data.imageUrl);
92setError(""); // Clear any previous errors
93} catch (err) {
103<Background />
104<div className="container">
105<h1 className="title">AI Image Generator</h1>
106<div className="input-container">
107<input
113/>
114</div>
115<button onClick={generateImage} disabled={loading || !prompt} className="generate-btn">
116{loading ? "Generating..." : "Generate Image"}
117</button>
118{error && <p className="error">{error}</p>}
119<div className="image-container">
120{latency !== null && (
121<p className="latency">Inference time (doesn't include network): {latency.toFixed(2)} ms</p>
123{loading
124? <LoadingSpinner />
125: <img src={imageUrl} alt="Generated image" className="generated-image" />}
126</div>
127<div className="footer">
193input: {
194prompt,
195image_size: "landscape_4_3",
196num_inference_steps: 4,
197num_images: 1,
198enable_safety_checker: true,
199sync_mode: true,
201});
202return new Response(
203JSON.stringify({ imageUrl: result.images[0].url, latency: result.timings.inference * 1000 }),
204{
205headers: { "Content-Type": "application/json" },
207);
208} catch (error) {
209return new Response(JSON.stringify({ error: "Failed to generate image" }), {
210status: 500,
211headers: { "Content-Type": "application/json" },
221<meta charset="UTF-8">
222<meta name="viewport" content="width=device-width, initial-scale=1.0">
223<title>AI Image Generator</title>
224<style>${css}</style>
225</head>
315text-align: center;
316}
317.image-container {
318margin-top: 20px;
319text-align: center;
322border-radius: 10px;
323}
324.generated-image {
325max-width: 100%;
326height: auto;
sqliteExplorerAppREADME.md1 match
3View and interact with your Val Town SQLite data. It's based off Steve's excellent [SQLite Admin](https://www.val.town/v/stevekrouse/sqlite_admin?v=46) val, adding the ability to run SQLite queries directly in the interface. This new version has a revised UI and that's heavily inspired by [LibSQL Studio](https://github.com/invisal/libsql-studio) by [invisal](https://github.com/invisal). This is now more an SPA, with tables, queries and results showing up on the same page.
45
67## Install
aiTextEditormain.tsx2 matches
233onChange: setEditorContent,
234className: "editor",
235formats: ["header", "bold", "italic", "underline", "strike", "blockquote", "list", "bullet", "indent", "link", "image"],
236modules: { toolbar: [['bold', 'italic', 'underline', 'strike'], ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], [{ 'list': 'ordered'}, { 'list': 'bullet' }], [{ 'script': 'sub'}, { 'script': 'super' }], [{ 'indent': '-1'}, { 'indent': '+1' }], [{ 'direction': 'rtl' }], ['link', 'image'], ['clean']] },
237preserveWhitespace: true,
238modules: { toolbar: true }
blob_adminREADME.md1 match
3This is a lightweight Blob Admin interface to view and debug your Blob data.
45
67Use this button to install the val:
7{
8headers: {
9"Content-Type": "image/svg+xml",
10"Cache-Control": `public, max-age=${60 * 60 * 24}, s-maxage=${60 * 60 * 24}`,
11},
linkInBioTemplatemain.tsx2 matches
84const tools = [
85{ name: 'MidJourney', description: 'Create stunning artwork with text prompts' },
86{ name: 'DALL-E', description: 'Generate images from textual descriptions' },
87{ name: 'Stable Diffusion', description: 'Open-source image generation model' },
88];
89
hasWebsiteChangedmain.tsx3 matches
29const img2Buf = Buffer.from(previousBuffer);
3031const previousImage = PNG.sync.read(img1Buf);
32const currentImage = PNG.sync.read(img2Buf);
3334try {
35const result = pixelmatch(previousImage.data, currentImage.data, null, previousImage.width, previousImage.height, {
36threshold,
37});