2026-02-26 13:59:51 +01:00
2026-06-15 12:14:41 +02:00
2026-07-16 12:23:11 +02:00
2026-01-27 15:11:51 +01:00
2026-06-15 12:26:13 +02:00
2026-06-30 11:35:17 +02:00
2025-03-17 13:16:57 -05:00
2026-05-06 13:40:28 +02:00
2026-05-06 14:25:42 +02:00
2026-07-21 13:51:14 +02:00

Goteo v4 Web

Frontend for the Goteo crowdfunding platform — built on Astro 7 + Svelte 5 + TailwindCSS 4, deployed on Cloudflare Workers.

Note

: This application is a client of the Goteo v4 API. You need a running v4 API instance and an OAuth client registered in it before this web app will work.

Installation

This application requires Node.js (v22.12 or later) and the pnpm package manager. It also needs a reachable Goteo v4 API instance to connect to.

1. Clone or download this repository.

git clone https://github.com/goteo/org.goteo.www
cd org.goteo.www

2. Install the dependencies.

pnpm install

3. Configure the environment.

Copy the example environment file and fill in the values for your setup.

cp .env.example .env

The minimum required values to boot the app and authenticate users are:

Variable Description
PUBLIC_API_URL Base URL of your Goteo v4 API instance (e.g. http://localhost:8090)
PUBLIC_API_VERSION API version — keep as v4
OAUTH2_CLIENT_ID / OAUTH2_CLIENT_SECRET Credentials of an OAuth client registered in the API. Must allow the grants authorization_code, refresh_token, password

NOTE: The OAuth client must exist in the v4 API instance. See the API's Authentication docs.

The remaining variables (tipping, Facebook share, object storage, HTTP Basic auth) are optional and the app falls back to sane defaults when they are empty. See .env.example for the full annotated list and the Environment variables section below.

Usage

Start the development server.

pnpm dev

The app should be live at http://localhost:4321.

The dev server runs on the Cloudflare Workers runtime (workerd), the same one used in production, with bindings read from wrangler.toml. No separate command is needed to reproduce the production runtime locally.

Other commands

Command Action
pnpm install Install dependencies
pnpm dev Dev server at localhost:4321 (Workers runtime)
pnpm build Build for production
pnpm preview Preview production build locally
pnpm format ESLint fix + Prettier write
pnpm check Prettier format check
pnpm openapi Regenerate OpenAPI SDK from live API spec
pnpm storybook Storybook dev server at localhost:6006
pnpm build-storybook Build Storybook static output
pnpm cypress:open Cypress E2E interactive
pnpm cypress:run Cypress E2E headless
pnpm test:e2e Start dev server + run Cypress headless
pnpm test:e2e:ci CI E2E against Workers preview build

Regenerating the API SDK

The TypeScript API client under src/openapi/client/ is generated from the live API's OpenAPI spec. Regenerate it whenever the API spec changes (requires the API running and PUBLIC_API_URL / PUBLIC_API_VERSION set):

pnpm openapi

This fetches the spec from $PUBLIC_API_URL/$PUBLIC_API_VERSION/docs.json. Commit the generated files together with any config change.

Testing

End-to-end tests use Cypress.

# Interactive runner
pnpm cypress:open

# Headless run against an already-running dev server
pnpm cypress:run

# Start the dev server and run the headless suite in one command
pnpm test:e2e

Component and unit tests run on Vitest through the Storybook test addon — launch Storybook to develop and visually check components:

pnpm storybook

Before opening a PR

pnpm format         # Fix formatting (ESLint + Prettier)
pnpm cypress:run    # E2E must pass

Debugging

Common issues you might run into while developing:

1. Blank pages or auth failures right after setup.

This almost always means the app cannot reach the API or the OAuth client is misconfigured. Check that:

  • PUBLIC_API_URL points to a reachable v4 API instance and includes the protocol (http:// / https://).
  • An OAuth client exists in that API instance and its OAUTH2_CLIENT_ID / OAUTH2_CLIENT_SECRET match your .env.
  • The OAuth client allows the authorization_code, refresh_token and password grants.

2. Type errors against the API after the API changed.

The generated SDK is out of date. Regenerate it (API must be running):

pnpm openapi

3. Errors about missing Node.js modules (fs, path, os, child_process, …).

The dev server and production both run on the Cloudflare Workers runtime, which has no Node.js APIs. Runtime code (pages, components, services) must use Web APIs (fetch, crypto, URL, Cache) instead. Move any Node-only logic to build-time code (config files, scripts, plugins), where it is still allowed.


Stack

Layer Technology
Framework Astro 7
UI Svelte 5 (runes), TailwindCSS 4
Language TypeScript 5
Runtime Cloudflare Workers (also supports Node)
API client @hey-api/client-fetch (generated OpenAPI)
Testing Vitest (unit), Cypress (E2E), Storybook

Routes

All user-facing pages live under src/pages/[...locale]/ (locale prefix: es, en, ca).

Route Page
/ Home
/search Project search
/project/[idOrSlug] Project detail
/project/[idOrSlug]/edit Project editor (auth)
/create/project Create project (auth)
/checkout Checkout cart
/checkout/payment Payment
/checkout/post-payment Post-payment confirmation
/checkout/verify Payment verification
/checkout/wallet Wallet confirmation
/login Login
/login/callback OAuth2 callback
/logout Logout
/register Register
/me My profile (auth)
/user/[idOrHandle] Public user profile
/about About
/static/[fileName] CMS static content
/admin/charges Admin contributions (auth)
/403, /404, /500 Error pages

API endpoints under src/pages/api/:

Endpoint Purpose
/api/relay/[...path] Authenticated API proxy
/api/upload/preupload S3 pre-signed URL generation
/api/upload/postupload S3 post-upload validation

Project Structure

src/
├── actions/          # Astro server actions (form mutations)
├── auth/             # JWT sessions, OAuth2 tokens, refresh logic
├── components/       # Svelte components (PascalCase filenames)
│   ├── library/      # Reusable UI primitives + Storybook stories
│   ├── Admin/        # Admin-specific components
│   ├── icons/        # Icon SVG components
│   └── [Feature]/    # Feature-scoped (project/, profile/, Checkout/, etc.)
├── firewall/         # Route access control rules
├── i18n/             # Translations (es/en/ca) + t() store
├── layouts/          # Astro layout components
├── middleware/       # Astro request middleware (auth, locale, firewall)
├── openapi/          # OpenAPI SDK (generated) + config
├── pages/            # Astro routes
│   ├── [...locale]/  # All user-facing pages under locale prefix
│   └── api/          # Server-side API endpoints
├── services/         # Business logic & API call wrappers
├── stores/           # Svelte stores (client-side state)
│   └── drafts/       # Project draft persistence (Dexie/IndexedDB)
├── stories/          # Full-page Storybook stories
├── styles/           # Global CSS + Tailwind theme tokens
├── svgs/             # SVG Svelte components
├── types/            # Shared TypeScript interfaces
└── utils/            # Pure helper functions
    └── drafts/       # Draft DB repository helpers

Environment variables

Full list lives in .env.example. Grouped by purpose:

Variable Required Purpose
PUBLIC_API_URL ✅ Base URL of the v4 API instance
PUBLIC_API_VERSION ✅ API version (v4)
OAUTH2_CLIENT_ID / OAUTH2_CLIENT_SECRET ✅ OAuth client credentials registered in the API
PUBLIC_DEFAULT_CURRENCY Fallback currency (e.g. EUR)
PUBLIC_DEFAULT_LANGUAGE Fallback locale (es, en, ca)
PUBLIC_DEFAULT_MAXSIZE Max upload size in bytes (default 8388608 = 8MB)
PUBLIC_TIPPING_TIPJAR_ID Tipjar ID — leave empty to disable tipping
PUBLIC_TIPPING_DEFAULT_AMOUNT Pre-filled tip amount
PUBLIC_TIPPING_DEFAULT_CHECKED "true" to pre-check the tip option
PUBLIC_FACEBOOK_APP_ID Facebook share dialog app ID
CLOUDFLARE_INCLUDE_PROCESS_ENV "true" — required for Cloudflare Workers to read env vars
BASIC_AUTH "true" to add an HTTP Basic auth layer (not a replacement for OAuth)
BASIC_AUTH_USERNAME / BASIC_AUTH_PASSWORD Credentials for the Basic auth layer
OBJECT_STORAGE_* S3-compatible storage (access key, secret, region, endpoint, bucket) for media upload

CI / Deployment

Workflow Trigger Action
deploy.yml Push to main Deploy to Cloudflare (production)
deploy.yml Push to develop Deploy to Cloudflare (staging)
cypress-tests.yml PR / push Cypress E2E headless
prettier-check.yml PR / push Prettier format check
S
Description
web interface to the DTF crowd fund platform forked from Goteo https://github.com/GoteoFoundation/goteo/pull/669
Readme
59 MiB
Languages
Svelte 63.1%
TypeScript 30%
Astro 5.9%
JavaScript 0.8%
CSS 0.2%