Read-only mirror of https://github.com/swissgeo/web-portal — SWISSGEO. Issues & pull requests at the source.
  • TypeScript 86.1%
  • Vue 13.4%
  • CSS 0.3%
  • Dockerfile 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jérémie Zurflüh b05e7f7c02
Merge pull request #425 from swissgeo/feat-gps-1067-adapt-drawing-state
GPS-1067: adapt drawing representation in global state
2026-10-16 08:34:45 +02:00
.github Added/Modified github workflows pr-auto-semver.yml #skip-tagging-and-release 2026-08-06 10:44:01 +02:00
.vscode fix: vscode config file 2026-05-19 12:09:53 +02:00
docs/adr GPS-502: accept adr 2026-02-23 11:37:51 +01:00
packages GPS-1067: use isDrawingLayerState type guard in review 2026-10-16 08:20:48 +02:00
test-utils GPS-670 format global files 2026-05-26 11:09:37 +02:00
tests GPS-1093: name the mobile search button 2026-10-13 10:59:37 +02:00
.dockerignore GPS-516: Update docker image for dev and prod target 2026-03-12 07:44:13 +01:00
.env.test GPS-1096: CMS search true for tests 2026-10-05 15:17:58 +02:00
.git-blame-ignore-revs GPS-670 add format hash to blame ignore 2026-05-26 11:10:14 +02:00
.gitignore GPS-833: removed pnpm cached file and gitignored the cache folder 2026-08-12 08:22:30 +02:00
.prettierignore GPS-456 Fix the prettier ignoring 2026-02-10 13:19:45 +01:00
base.vite.config.ts GPS-670 format global files 2026-05-26 11:09:37 +02:00
codecov.yml GPS-747 add Codecov configuration file and update README with coverage badge 2026-06-18 14:51:01 +02:00
CONTRIBUTION.md GPS-670 format global files 2026-05-26 11:09:37 +02:00
docker-compose.yml chore(deps): update all non-major dependencies, update tests 2026-09-21 09:56:08 +02:00
Dockerfile GPS-794 Bundle OTEL dependencies correctly 2026-07-03 16:10:37 +02:00
LICENSE.md Initial commit 2025-12-01 12:16:11 +01:00
package.json Update all non-major dependencies 2026-07-27 17:56:15 +02:00
playwright.config.ci.ts GPS-670 format global files 2026-05-26 11:09:37 +02:00
playwright.config.ts GPS-1096: CMS search true for tests 2026-10-05 15:17:58 +02:00
pnpm-lock.yaml GPS-892: fix conflicts 2026-10-13 15:32:18 +02:00
pnpm-workspace.yaml GPS-892: addressing review 2026-10-13 15:32:18 +02:00
prettier.config.ts GPS-670 format global files 2026-05-26 11:09:37 +02:00
README.md GPS-903: open the selected content page in a new tab 2026-09-18 09:52:48 +07:00
renovate.json GPS-892: addressing review 2026-10-13 15:32:18 +02:00
turbo.json GPS-747 update dependencies and add coverage testing commands 2026-06-18 14:50:59 +02:00

SWISSGEO Web Portal

Branch Status
develop Build Status codecov-develop
main Build Status codecov-main

This repository contains the frontend implementation for SWISSGEO, the future central geodata platform for Switzerland.

Important

This project is currently under active development. Features and documentation are subject to frequent changes.

Project Context

SWISSGEO is the upcoming unified hub for Swiss geospatial data, merging federal and cantonal services (geo.admin.ch, geodienste.ch, geocat.ch) into a single, modern infrastructure.

ℹ️ Resources

Project overview: Official SWISSGEO Platform info in German or French Version here (FR)

Quick-Start

Install all the dependencies:

pnpm install

Compile the sub-packages in watch mode (terminal 1):

pnpm turbo build:dev:watch

Run the dev server for coding (terminal 2):

pnpm run dev

Environment Variables

Before running the dev server, copy the example file and fill in the values:

cp packages/main/.env.example packages/main/.env

The available variables are:

NUXT_PUBLIC_OGC_API_ENDPOINT=   # OGC API endpoint (exposed to client)
NUXT_PUBLIC_WANTED_LOG_LEVELS=  # String of log levels wanted (error|warn|info|debug)
NUXT_PUBLIC_SHARE_SERVICE_URL=  # The URL to the share service
NUXT_WHAT3WORDS_API_KEY=        # what3words API key (server-only)
NUXT_GEOADMIN_API_BASE_URL=     # Base URL for legacy geo.admin.ch API (server-only)
NUXT_PUBLIC_CMS_BASE_URL=        # Published CMS site, for linking search results (exposed to client)
NUXT_LIVINGDOCS_API_ENDPOINT=   # Livingdocs CMS public API, incl. version (server-only)
NUXT_LIVINGDOCS_AUTH_TOKEN=     # Livingdocs project-scoped API token (server-only)

Monorepo setup

This project is structed as a monorepo. There are several sub-packages, each with a specific purpose. This way, the code is forced to stay cleaner and the various parts have to be more abstracted.

The main entrypoint is the main package. It contains the necessary nuxt setup to provide the final application.

The layers package handles the addition of layers to the application. The intention of this package is to keep it as stupid as possible: don't add anything map related to this.

The map package's purpose is to display map. As of now, this means all the required code to fetch the data to create an openlayers map.

Since we still have to share some types and data structures across the packages, there is a package shared for that.

The skeleton package contains UI elements and things that are not specific to a specific page/view of the app.

In the future, we'll have content from a CMS in this webapp. This package takes care of that.

Docker

A Dockerfile is provided to build and run the application in a container. It accepts a TARGET_ENV build argument (prod by default).

Build the image:

# build with source maps
pnpm run docker:build:dev

# build without source maps
pnpm run docker:build:prod

Run the container:

# with source maps
pnpm run docker:run:dev

# or without source maps
pnpm run docker:run:prod

The app will be available at http://localhost:3000.

Note: Environment variables (NUXT_API_ENDPOINT, NUXT_AUTH_TOKEN, NUXT_MAPTILER_API_KEY, etc.) must be set at runtime via -e flags or an env file — do not bake secrets into the image.

Turbo

The repo makes use of Turbo, a supercharger for monorepos. Turbo caches the outcome of certain scripts and won't re-run it if its not needed.

What you can do is, instead of just using pnpm run build|lint|format|type-check is to use pnpm turbo build|lint|format|type-check. This will engage the wrapper and make use of these functionalities and speed up your workflow!

Integration tests

Integration tests live in tests/integration/ and use Playwright. They verify that UI components work together correctly (sidebar, map canvas, toolbox, locale routing) without depending on real external services — all outgoing API requests are mocked via page.route().

The first time you run them locally, install the browser binary:

pnpm exec playwright install --with-deps chromium

Then build the library packages (the Nuxt dev server imports them from their dist/ output):

pnpm build:dev

Run the tests:

pnpm test:integration

Playwright auto-starts the Nuxt dev server on http://localhost:3000. If you already have pnpm run dev running, it will reuse that server.

Note: The first page load in dev mode can take 30–45s while Vite compiles modules on demand. Subsequent test runs in the same session are fast thanks to HMR.

In CI (AWS CodeBuild) the tests run against a production preview (pnpm --filter main preview) after a full pnpm build, which avoids the dev-mode cold-start delay. The Playwright config switches automatically when CI=true is set.

Renovate

This repository is monitored by a Renovate Bot. This means it will periodically receive pull requests on github wanting to update certain dependencies.

Basic workflow:

  1. Renovate creates a branch with updated pnpm-workspace.yml and pnpm-lock.yml
  2. All tests succeed: approve the PR and merge it
  3. Some tests fail:
  • check out the branch and fix
  • close the PR (renovate will ignore this package until a new version is released)

Advanced configurations

If you want to exclude a specific package from renovate scans, you can exclude that package in the renovate.json config. Add the package name to the ignoreDeps array:

{
  "ignoreDeps": ["ol", "@nuxt/ui"]
}

Use the exact package name as it appears in the catalog: block of pnpm-workspace.yaml. Renovate will stop opening update PRs for those packages entirely, so add a comment to the PR or a note here explaining why a package is pinned — otherwise it is easy to forget that it is being held back.