101 lines
3.1 KiB
Markdown
101 lines
3.1 KiB
Markdown
# Drizz.li
|
|
|
|
An open-source, high-performance weather forecast website built with SvelteKit and powered by the [Open-Meteo APIs](https://open-meteo.com/).
|
|
|
|
## 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](https://kit.svelte.dev/)
|
|
- **Language**: [TypeScript](https://www.typescriptlang.org/)
|
|
- **Data Source**: [Open-Meteo API](https://open-meteo.com/)
|
|
- **Visualization**: custom canvas charts (`src/lib/charts`)
|
|
|
|
## Developing
|
|
|
|
Once you've cloned the project and installed dependencies with `npm install`:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
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.
|
|
|
|
Serve it as an **internal rewrite (200)**, not as an error page. `error_page
|
|
404 /404.html` sends the right body with a 404 status: the page works, but
|
|
every hard reload of an unprerendered URL logs a 404 in the network panel and
|
|
tells crawlers the page does not exist. `try_files` with a URI as its last
|
|
argument does an internal redirect instead, and answers 200.
|
|
|
|
### 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
|
|
|
|
```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
|
|
|
|
```nginx
|
|
server {
|
|
server_name drizzli.example.com;
|
|
root /srv/drizzli;
|
|
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
|
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
|
location / {
|
|
# the trailing /404.html is a URI, so nginx rewrites internally and
|
|
# answers 200 - `error_page 404 /404.html` would answer 404 instead
|
|
try_files $uri $uri/index.html /404.html;
|
|
}
|
|
}
|
|
```
|