This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Photography Weather Dashboard called "Kur saulytė?" - a dense, mobile-first weather website designed for photographers to quickly check upcoming weather conditions with focus on cloud cover, visibility, and lighting conditions. The app provides hourly weather data for 7 days with photography-specific scoring and golden hour detection.
├── backend/
│ └── index.ts # Hono server with Open-Meteo SDK integration
├── frontend/
│ ├── index.html # Main HTML page
│ ├── index.tsx # React app with weather dashboard UI
│ └── style.css # Mobile-optimized styles with responsive grid
├── deno.json # Deno configuration
└── README.md
serveFile
, readFile
)/api/weather?lat={lat}&lon={lon}
- Weather data with photography insights/api/location
- Auto-detect location from IP with Amsterdam fallback/api/geocode?q={query}
- Search locations by city/area nameSince this is a Val Town project, there are no traditional build commands. Development happens directly on the platform.
When extending this project, you can use Val Town's hosted services:
import { blob } from "https://esm.town/v/std/blob";
await blob.setJSON("myKey", { hello: "world" });
let data = await blob.getJSON("myKey");
let keys = await blob.list("app_");
await blob.delete("myKey");
import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
const TABLE_NAME = 'weather_cache_1';
// Create table - change table name when modifying schema
await sqlite.execute(`CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
location TEXT NOT NULL,
data TEXT NOT NULL,
timestamp INTEGER
)`);
const result = await sqlite.execute(`SELECT * FROM ${TABLE_NAME} WHERE location = ?`, ["Amsterdam"]);
import { email } from "https://esm.town/v/std/email";
await email({
subject: "Weather Alert",
text: "Perfect photography conditions detected!",
html: "<h1>Perfect photography conditions detected!</h1>"
});
import { OpenAI } from "https://esm.town/v/std/openai";
const openai = new OpenAI();
const completion = await openai.chat.completions.create({
messages: [{ role: "user", content: "Describe this weather for photography" }],
model: "gpt-4o-mini",
max_tokens: 100,
});
https://esm.sh
for all imports to ensure browser/server compatibility/** @jsxImportSource https://esm.sh/react@19 */
at top of React filesDeno.env.get()
for secrets (never bake into code)alert()
, prompt()
, or confirm()
return new Response(null, { status: 302, headers: { Location: "/path" }})
for redirectsResponse.redirect()
is broken - use manual redirect headers instead<script src="https://esm.town/v/std/catch"></script>
to HTML for client-side error debuggingserveStatic
middleware - it doesn't work on Val Townimport { readFile, serveFile } from "https://esm.town/v/std/utils/index.ts"
import { deleteCookie, getCookie, setCookie } from "npm:hono/cookie"
This project uses HTTP triggers, but Val Town supports multiple trigger types:
export default async function (email: Email) {
// Could process weather alert subscription emails
}
Always import with version pins:
import { readFile, serveFile, listFiles } from "https://esm.town/v/std/utils@85-main/index.ts";
Important: These utilities ONLY run on the server. Pass data to client via HTML injection or API calls.
This is a Val Town project that auto-deploys on save. No traditional CI/CD pipeline.
For local development testing:
shared/
must work in both frontend and backend (no Deno
keyword)readFile
helpers for project files<img src="https://maxm-imggenurl.web.val.run/description" />
<script src="https://cdn.twind.style" crossorigin></script>