Commit Graph
247 Commits
Author SHA1 Message Date
leanderandClaude Opus 5.5 2e54e32ea6 Add canonical URLs, hreflang alternates and article metadata
Set metadataBase so relative metadata URLs resolve to the real domain,
link the Norwegian and English versions of each page, and mark blog
posts as articles with their publish date and author.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:59:56 +01:00
leanderandClaude Opus 5.5 115afd4275 Make the Back button aware of client-side navigation
document.referrer only changes on full page loads, so the button sent
visitors to the home page instead of back after navigating within the
site. Use the Navigation API's canGoBack, which only considers this
site's history entries, and keep the referrer check as a fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:57:28 +01:00
leanderandClaude Opus 5.5 67641c5719 Don't open mailto: and internal links in a new tab
target="_blank" on mailto: links leaves an empty tab behind. In blog
posts, only links to other sites now open in a new tab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:56:08 +01:00
leanderandClaude Opus 5.5 70ba50c515 Hide decorative flags from screen readers in the language selector
The flags had titles that repeated the button text. Also mark each
language name with its own lang so it's pronounced correctly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:54:18 +01:00
leanderandClaude Opus 5.5 633237f262 Make the "Other" dropdown accessible
Expose its state with aria-expanded, close it on outside clicks,
Escape and when focus leaves, restore the focus outline, and move the
inline margins into CSS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:53:03 +01:00
leanderandClaude Opus 5.5 eab0e0bbab Use a span instead of a paragraph inside the Back button
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:51:56 +01:00
leanderandClaude Opus 5.5 7822daa557 Add CI workflow that checks pull requests
Run formatting, lint, type checking and a production build on every
pull request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:51:03 +01:00
leanderandClaude Opus 5.5 773d21b709 Shorten deploy downtime and limit workflow permissions
Build the new image before replacing the running container instead of
stopping the site first, prune old images, prevent overlapping deploys,
and drop the unused pull-requests permission.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:40:21 +01:00
leanderandClaude Opus 5.5 b8e352ba22 Use a multi-stage Docker build with Next's standalone output
Install with npm ci, ship only the standalone server and its traced
dependencies, and run as a non-root user. Shrinks the image from
1.78 GB to 438 MB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:39:14 +01:00
leanderandClaude Opus 5.5 703ab5a32c Only send translations used by client components to the browser
Server components read their translations on the server, but every
namespace was serialized into each page for the client provider.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:30:41 +01:00
leanderandClaude Opus 5.5 edf0eed3dc Lazy-load the MazeMap iframe
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:28:03 +01:00
leanderandClaude Opus 5.5 1d506a7b4c Fix deprecated Prettier option and make the repo pass prettier --check
jsxBracketSameLine was replaced by bracketSameLine in Prettier 3.
Ignore tsconfig.json, since Next rewrites it in its own format.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:27:37 +01:00
leanderandClaude Opus 5.5 aca183a4a2 Use the @/ import alias consistently
Drop the @components and @lib aliases, which only a few imports used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:26:06 +01:00
leanderandClaude Opus 5.5 3a0ad44e06 Define icons, theme color and viewport once
Icons were set in both the layout metadata and every page's metadata,
and theme-color was output twice. Inherit icons from the layout and
export the viewport from the layout instead of from each page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:25:05 +01:00
leanderandClaude Opus 5.5 0eb47846e7 Simplify Umami analytics into one server component
The config was split between lib/analyticsConfig and a client component
that repeated the production check and default URL, and checked window
during render. Umami's data-domains already restricts tracking to our
domains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:23:06 +01:00
leanderandClaude Opus 5.5 5c612d995d Share event date handling and stop depending on the server timezone
Event dates are stored as Oslo wall-clock strings, but were parsed in
the server's local timezone, so times were only correct because the
container sets TZ=Europe/Oslo. Move date parsing and formatting into
lib/dates, interpret those strings as Oslo time, and also accept ISO
timestamps in case the Studio writes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:20:46 +01:00
leanderandClaude Opus 5.5 35c175c1ad Remove unused translation key and query field
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:18:02 +01:00
leanderandClaude Opus 5.5 19cda1b817 Remove accidentally added install package
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:16:24 +01:00
leanderandClaude Opus 5.5 7c344a2c74 Rename middleware.ts to proxy.ts
The middleware file convention is deprecated in Next 16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:15:24 +01:00
leanderandClaude Opus 5.5 5b135ce712 Define locales once with next-intl's routing config
Locales were listed separately in the middleware, the request config
and several type casts. Use defineRouting and createNavigation, type
the Locale globally, and let the language selector use the locale-aware
router so it keeps the query string and hash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:13:57 +01:00
leander b84781ebe5 remove unused i18n request config 2026-10-30 22:10:42 +01:00
leanderandClaude Opus 5.5 aca584791e Update Node to 26 and dependencies to their latest versions
- Node 20 is end-of-life; use the current LTS in the Docker image
- Major updates: @sanity/client 8, @sanity/image-url 2,
  @portabletext/react 8, eslint-config-next 16
- Unpin React and update to 19.3
- ESLint stays on 9 and TypeScript on 6.0, since eslint-config-next's
  plugins and typescript-eslint don't support newer majors yet
- Use the native flat config from eslint-config-next 16
- Use useSyncExternalStore for WebGL detection to satisfy the new
  react-hooks lint rule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:01:56 +01:00
leanderandClaude Opus 5.5 a1729494b4 Only render safe link URLs from blog content
Blog links come from the CMS, so a javascript: URL would run code when
clicked. Allow only http(s), mailto and relative links, and render
anything else as plain text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:51:53 +01:00
leanderandClaude Opus 5.5 d04afb3e0c Use real links in the "Other" dropdown
The items were buttons calling window.open() without noopener, which
let the opened page access window.opener. Links also support
middle-click and show the URL on hover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:50:23 +01:00
leanderandClaude Opus 5.5 c997b74d01 Verify Sanity webhook signatures in the revalidate route
The secret was passed in the query string, which ends up in access logs
and doesn't protect the request body. Verify the signed header with
@sanity/webhook instead, and return 400 for invalid JSON.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:48:49 +01:00
leanderandClaude Opus 5.5 c5c366884a Fetch only upcoming events from Sanity
Filter and limit in GROQ instead of fetching every event and filtering
in JavaScript. Event dates are stored as Oslo local time strings, so
compare them against the current Oslo time in the same format.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:46:06 +01:00
leanderandClaude Opus 5.5 b05ecf757d Handle events without a description
Event cards crashed on a missing description, and the event metadata
included "null" for missing fields. Truncate previews by grapheme so
emoji aren't split, and show descriptions of exactly 70 characters in
full.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:41:07 +01:00
leanderandClaude Opus 5.5 1f82345a2f Keep .env and local build artifacts out of the Docker image
Without a .dockerignore, COPY . . baked the .env file (including the
webhook secret) into the image and overwrote the container's
node_modules with the host's. Pass public build-time values as build
args and provide the rest at runtime through env_file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:38:49 +01:00
leander d03278ef0d replace deprecated next lint with eslint 2026-10-30 21:30:12 +01:00
leanderandClaude Opus 5.5 da3d26d16b Render pages statically using next/root-params
getLocale() read request headers, which made every route dynamic and the
page-level revalidate a no-op. Make [locale]/layout.tsx the root layout
so the locale can be read through next/root-params, set <html lang>, add
generateStaticParams for locales and slugs, and pass the locale
explicitly to metadata translations.

The middleware now matches all non-file paths so URLs without a locale
are redirected instead of hitting the root layout's notFound().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:28:32 +01:00
leanderandClaude Opus 5.5 a8b31a5379 Expire cache tags immediately on webhook revalidation
The "max" profile serves stale content once more while revalidating, so
the first visit after publishing showed the old version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:18:07 +01:00
leander 30da54c78e use next cache instead of sanity's cache 2026-10-30 21:16:08 +01:00
leander 13463d4eeb fetch board member data on data change 2026-10-30 21:13:58 +01:00
leander d44fbfa9d7 fix 404 page i18n handling 2026-10-30 21:11:53 +01:00
leander 52b8f2b7b7 remove redundant layout tags 2026-10-30 21:03:53 +01:00
leander 38f1ba69b4 return 404 on no data for blogposts/events 2026-10-30 21:02:32 +01:00
leander 39ad3947fd run npm audit fix 2026-10-30 15:49:10 +01:00
leander 14c1403e6d fix some vulns 2026-10-22 19:04:06 +02:00
leander e238eed619 clarify webhook api deployment 2026-09-10 02:17:26 +02:00
leander 08bc43942a fix vulns 2026-08-29 16:47:38 +02:00
leander b0e343a390 Merge pull request #55 from UiO-Gaming/dependabot/npm_and_yarn/multi-5a59400ff4
Bump brace-expansion
2026-08-28 21:08:07 +02:00
leander c7d646362b Merge pull request #54 from UiO-Gaming/dependabot/npm_and_yarn/next-15.5.24
Bump next from 15.5.18 to 15.5.24
2026-08-28 21:07:32 +02:00
dependabot[bot] 2183175de6 Bump brace-expansion
Bumps  and [brace-expansion](https://github.com/juliangruber/brace-expansion). These dependencies needed to be updated together.

Updates `brace-expansion` from 1.1.14 to 1.1.18
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.14...v1.1.18)

Updates `brace-expansion` from 2.1.0 to 2.1.4
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.14...v1.1.18)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.18
  dependency-type: indirect
- dependency-name: brace-expansion
  dependency-version: 2.1.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-28 19:05:43 +00:00
dependabot[bot] bf6f282155 Bump next from 15.5.18 to 15.5.24
Bumps [next](https://github.com/vercel/next.js) from 15.5.18 to 15.5.24.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/compare/v15.5.18...v15.5.24)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.5.24
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-28 19:04:30 +00:00
leander 8480327a4c Merge pull request #53 from UiO-Gaming/dependabot/npm_and_yarn/next-15.5.18
Bump next from 15.5.15 to 15.5.18
2026-05-14 22:35:19 +08:00
dependabot[bot] 30abf637ac Bump next from 15.5.15 to 15.5.18
Bumps [next](https://github.com/vercel/next.js) from 15.5.15 to 15.5.18.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.5.15...v15.5.18)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.5.18
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 13:45:01 +00:00
leander 93b2dc4d4e fix vulns 2026-04-14 04:25:01 +02:00
leander 183e519a19 fix CVE-2026-27903 2026-03-23 15:14:15 +01:00
leander 1c02352aad add section ids
allow linkink to certain parts of the homepage
2026-03-09 21:03:48 +01:00
leander abcc39ce6d fix GHSA-h25m-26qc-wcjf 2026-02-14 15:41:52 +01:00