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>
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>
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>
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>
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>
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>
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>
fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple fuck apple
Rerendering translations apparently caused issues with safari because
apple fucking sucks. Thus we had to rewrite the logic to use
prefix-based translations. This is the attempt at this. It might be a
mega commit but it's how it ought to be...