Drizzli
An open-source, high-performance weather forecast website built with SvelteKit and powered by the Open-Meteo APIs.
Goals
Our objective is to provide a comprehensive, user-friendly weather platform for end-users. We aim to offer professional-grade weather visualizations and detailed meteorological data while maintaining the transparency and community-driven nature of open-source software.
Tech Stack
- Framework: SvelteKit
- Language: TypeScript
- Data Source: Open-Meteo API
- Visualization: custom canvas charts (
src/lib/charts)
Developing
Once you've cloned the project and installed dependencies with npm install:
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
Building
To create a production version of your app:
npm run build
You can preview the production build with npm run preview.
Deployment (static hosting)
The build output in build/ is a fully static site. Two pieces of server
configuration are needed:
1. SPA fallback
Pages that are not prerendered (unlisted cities, GPS coordinate routes like
/weather/week/52.09N5.12E/) are served by 404.html, which boots the app
and resolves the location client-side. Configure the server to serve
404.html for unknown paths.
2. Cross-origin isolation (SharedArrayBuffer for the embedded map)
The /weather/maps/ page embeds maps.open-meteo.com, which uses
SharedArrayBuffer for its decoding worker pool. A cross-origin iframe only
gets SharedArrayBuffer when the embedding page is cross-origin
isolated, so this site must be served with:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
(The map already serves Cross-Origin-Resource-Policy: cross-origin and its
own COOP/COEP, so it is embeddable under these headers. All other assets are
same-origin and the weather APIs are CORS requests, so require-corp is safe
here.)
Example: Caddy
drizzli.example.com {
root * /srv/drizzli
file_server
try_files {path} {path}/ /404.html
header {
Cross-Origin-Opener-Policy "same-origin"
Cross-Origin-Embedder-Policy "require-corp"
}
}
Example: nginx
server {
server_name drizzli.example.com;
root /srv/drizzli;
error_page 404 /404.html;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
location / {
try_files $uri $uri/ =404;
}
}