Files
web/apps/scandic-web/next.config.ts
Joakim Jäderberg ae7a62c88f Merged in feature/SW-3149-send-logs-to-sentry (pull request #2802)
Feature/SW-3149 send logs to sentry

* Use sentry for logging

* .

* fix(SW-3149) Send logs to Sentry

* remove experimental flag for logs

* add sentry settings for partner-sas

* feat(SW-3108): Added external link option to top primary button on content/collection page

Approved-by: Matilda Landström

* fix(BOOK-152): Removed old header references inside useStickyPosition hook to fix offset issue for the sitewide alert

Approved-by: Matilda Landström

* Merged in fix/LOY-360-team-member-text-for-retired-employees (pull request #2799)

fix(LOY-360): improve text for retired employees

* fix(LOY-360): improve text for retired employees


Approved-by: Erik Tiekstra
Approved-by: Matilda Landström

* Merged in fix/STAY-67-redirect-to-webview-after-gla (pull request #2795)

fix(STAY-67): redirect to webview after guarantee on my stay

* fix(STAY-67): redirect to webview after guarantee on my stay

* fix(STAY-67): add callback page for guarantee on webview


Approved-by: Linus Flood

* feat(SW-3152): Respecting image aspect ratio inside image gallery/lightbox

* feat(SW-3152): Respecting image aspect ratio inside image gallery/lightbox
* feat(BOOK-144): Make image clickable instead of a button to avoid being able to click outside of the image area

Approved-by: Bianca Widstam
Approved-by: Chuma Mcphoy (We Ahead)

* Merged in fix/BOOK-127-translate-validation-text (pull request #2800)

fix(BOOK-127): translate terms required message

* fix(BOOK-127): translate terms required message


Approved-by: Erik Tiekstra

* Merged in feat/LOY-354-L7-Progress-Card (pull request #2786)

Feat/LOY-354 L7 Progress Card

* feat(LOY-354): Add Trophy icon

* fix(LOY-354): include new tierPoints value

* feat(LOY-354): L7 Progress Level Card support

* refactor(LOY-354): Refactoring of component structure

* fix(LOY-354): Remove intl prop drilling

* fix(LOY-354): cleanup progress section code


Approved-by: Erik Tiekstra

* Merged in fix/BOOK-132-tracking-breakfast (pull request #2803)

fix(BOOK-132): add breakfastOption tracking

* fix(BOOK-132): add breakfastOption tracking


Approved-by: Joakim Jäderberg

* Merged in fix/enter-details-errors-missing (pull request #2806)

fix: Add missing messages to BookingFlowInput errors

* Add missing messages to BookingFlowInput errors

* Fix errors

* zippy zip

* phoney


Approved-by: Bianca Widstam
Approved-by: Joakim Jäderberg

* Merged in feature/copy-static-files-via-build-scripts (pull request #2798)

SW-3467 Copy static files via build scripts

* add file copy script and add all fonts to design-system

* add file copy script and add all fonts to design-system

* add file copy script and add all fonts to design-system

* remove fonts that will be copied via build scripts

* wip

* update paths to shared files

* update material-symbol script

* merge

* fix missing shared segment for path in fonts.css


Approved-by: Linus Flood

* Merged in feat/SW-2999-cleanup (pull request #2810)

feat(SW-2999): cleanup current web

* feat(SW-2999): cleanup current web

* Merge master

* Removed unused fonts


Approved-by: Joakim Jäderberg

* Merge branch 'master' of bitbucket.org:scandic-swap/web into feature/SW-3149-send-logs-to-sentry

* Merge branch 'master' of bitbucket.org:scandic-swap/web into feature/SW-3149-send-logs-to-sentry

* merge


Approved-by: Linus Flood
2025-09-18 07:59:44 +00:00

472 lines
13 KiB
TypeScript

import { fileURLToPath } from "node:url"
import * as Sentry from "@sentry/nextjs"
import createJiti from "jiti"
import { findMyBookingRoutes } from "@scandic-hotels/common/constants/routes/findMyBookingRoutes"
import {
login,
logout,
} from "@scandic-hotels/common/constants/routes/handleAuth"
import { myPages } from "@scandic-hotels/common/constants/routes/myPages"
import {
myStay,
preliminaryReceipt,
} from "@scandic-hotels/common/constants/routes/myStay"
import {
myStay as myStayWebview,
preliminaryReceipt as preliminaryReceiptWebview,
} from "./constants/routes/webviews"
const jiti = createJiti(fileURLToPath(import.meta.url))
jiti("./env/server")
jiti("./env/client")
/** @type {import('next').NextConfig} */
const nextConfig = {
env: {
BRANCH: process.env.BRANCH || "local",
GIT_SHA: process.env.COMMIT_REF || "",
},
poweredByHeader: false,
eslint: { ignoreDuringBuilds: true },
trailingSlash: false,
transpilePackages: [
"@scandic-hotels/common",
"@scandic-hotels/trpc",
"@scandic-hotels/booking-flow",
"@scandic-hotels/design-system",
],
experimental: {
serverActions: {
allowedOrigins: [
"*--web-scandic-hotels.netlify.app",
"develop--web-scandic-hotels.netlify.app",
"stage--web-scandic-hotels.netlify.app",
"test--web-scandic-hotels.netlify.app",
"master--web-scandic-hotels.netlify.app",
"*.scandichotels.com",
],
},
swcPlugins: [
[
"@swc/plugin-formatjs",
{
ast: true,
},
],
],
},
images: {
minimumCacheTTL: 2678400, // 31 days
deviceSizes: [320, 420, 768, 900, 1024, 1200, 2400],
imageSizes: [200, 400, 800, 1200, 1920],
remotePatterns: [
{
protocol: "https",
hostname: "eu-images.contentstack.com",
pathname: "/v3/assets/**",
},
{
protocol: "https",
hostname: "scandichotels.com",
},
{
protocol: "https",
hostname: "*.scandichotels.com",
},
// Tripadvisor CDN for award images
{
protocol: "https",
hostname: "static.tacdn.com",
},
],
},
logging: {
fetches: {
fullUrl: true,
},
},
output: "standalone",
webpack: function (config: any) {
config.module.rules.push(
{
test: /\.(graphql|gql)/,
exclude: /node_modules/,
loader: "graphql-tag/loader",
},
{
test: /\.svg$/,
use: ["@svgr/webpack"],
}
)
return config
},
// https://nextjs.org/docs/app/api-reference/next-config-js/redirects#header-cookie-and-query-matching
redirects() {
// Param checks needs to be split as Next.js handles everything
// in the missing array as AND, therefore they need to be separate
// to handle when one or more are missing.
//
// Docs: all missing items must not match for the redirect to be applied.
return [
{
// ----------------------------------------
// hotel (hotelId) param missing
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "hotel",
type: "query",
value: undefined,
},
],
permanent: false,
},
{
// ----------------------------------------
// hotel (hotelId) param has to be an integer
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "hotel",
type: "query",
value: "^[0-9]+$",
},
],
permanent: false,
},
{
// ----------------------------------------
// fromdate param missing
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "fromdate",
type: "query",
value: undefined,
},
],
permanent: false,
},
{
// ----------------------------------------
// fromdate param has to be a date
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "fromdate",
type: "query",
value: "^([12]\\d{3}-(0[1-9]|1[0-2])-(0?[1-9]|[12]\\d|3[01]))$",
},
],
permanent: false,
},
{
// ----------------------------------------
// todate param missing
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "todate",
type: "query",
value: undefined,
},
],
permanent: false,
},
{
// ----------------------------------------
// todate param has to be a date
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "todate",
type: "query",
value: "^([12]\\d{3}-(0[1-9]|1[0-2])-(0?[1-9]|[12]\\d|3[01]))$",
},
],
permanent: false,
},
{
// ----------------------------------------
// room[0].adults param missing
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "room[0].adults",
type: "query",
value: undefined,
},
],
permanent: false,
},
{
// ----------------------------------------
// room[0].adults param has to be an integer
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "room[0].adults",
type: "query",
value: "^[0-9]+$",
},
],
permanent: false,
},
{
// ----------------------------------------
// room[0].ratecode param missing
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "room[0].ratecode",
type: "query",
value: undefined,
},
],
permanent: false,
},
{
// ----------------------------------------
// room[0].roomtype param missing
// ----------------------------------------
source: "/:lang/hotelreservation/details",
destination: "/:lang/hotelreservation/select-rate",
missing: [
{
key: "room[0].roomtype",
type: "query",
value: undefined,
},
],
permanent: false,
},
]
},
rewrites() {
return {
beforeFiles: [
{ source: login.da, destination: "/da/login" },
{ source: login.de, destination: "/de/login" },
{ source: login.fi, destination: "/fi/login" },
{ source: login.no, destination: "/no/login" },
{ source: login.sv, destination: "/sv/login" },
{ source: logout.da, destination: "/da/logout" },
{ source: logout.de, destination: "/de/logout" },
{ source: logout.fi, destination: "/fi/logout" },
{ source: logout.no, destination: "/no/logout" },
{ source: logout.sv, destination: "/sv/logout" },
{
source: `${myPages.en}/:path*`,
destination: `/en/my-pages/:path*`,
},
{
source: `${myPages.da}/:path*`,
destination: `/da/my-pages/:path*`,
},
{
source: `${myPages.de}/:path*`,
destination: `/de/my-pages/:path*`,
},
{
source: `${myPages.fi}/:path*`,
destination: `/fi/my-pages/:path*`,
},
{
source: `${myPages.no}/:path*`,
destination: `/no/my-pages/:path*`,
},
{
source: `${myPages.sv}/:path*`,
destination: `/sv/my-pages/:path*`,
},
{
source: "/:lang/hotelreservation/payment-callback/:status",
destination:
"/:lang/hotelreservation/payment-callback?status=:status",
},
// Find my booking
{
source: findMyBookingRoutes.en,
destination: "/en/hotelreservation/get-booking",
},
{
source: findMyBookingRoutes.da,
destination: "/da/hotelreservation/get-booking",
},
{
source: findMyBookingRoutes.de,
destination: "/de/hotelreservation/get-booking",
},
{
source: findMyBookingRoutes.fi,
destination: "/fi/hotelreservation/get-booking",
},
{
source: findMyBookingRoutes.no,
destination: "/no/hotelreservation/get-booking",
},
{
source: findMyBookingRoutes.sv,
destination: "/sv/hotelreservation/get-booking",
},
// My stay
{
source: `${myStay.en}`,
destination: "/en/hotelreservation/my-stay",
},
{
source: `${myStay.sv}`,
destination: "/sv/hotelreservation/my-stay",
},
{
source: `${myStay.da}`,
destination: "/da/hotelreservation/my-stay",
},
{
source: `${myStay.de}`,
destination: "/de/hotelreservation/my-stay",
},
{
source: `${myStay.fi}`,
destination: "/fi/hotelreservation/my-stay",
},
{
source: `${myStay.no}`,
destination: "/no/hotelreservation/my-stay",
},
// My stay receipt
{
source: `${preliminaryReceipt.en}`,
destination: "/en/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceipt.sv}`,
destination: "/sv/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceipt.da}`,
destination: "/da/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceipt.de}`,
destination: "/de/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceipt.fi}`,
destination: "/fi/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceipt.no}`,
destination: "/no/hotelreservation/my-stay/receipt",
},
// Webview My stay
{
source: `${myStayWebview.en}`,
destination: "/en/webview/hotelreservation/my-stay",
},
{
source: `${myStayWebview.sv}`,
destination: "/sv/webview/hotelreservation/my-stay",
},
{
source: `${myStayWebview.da}`,
destination: "/da/webview/hotelreservation/my-stay",
},
{
source: `${myStayWebview.de}`,
destination: "/de/webview/hotelreservation/my-stay",
},
{
source: `${myStayWebview.fi}`,
destination: "/fi/webview/hotelreservation/my-stay",
},
{
source: `${myStayWebview.no}`,
destination: "/no/webview/hotelreservation/my-stay",
},
// Webview My stay receipt
{
source: `${preliminaryReceiptWebview.en}`,
destination: "/en/webview/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceiptWebview.sv}`,
destination: "/sv/webview/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceiptWebview.da}`,
destination: "/da/webview/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceiptWebview.de}`,
destination: "/de/webview/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceiptWebview.fi}`,
destination: "/fi/webview/hotelreservation/my-stay/receipt",
},
{
source: `${preliminaryReceiptWebview.no}`,
destination: "/no/webview/hotelreservation/my-stay/receipt",
},
// Sitemap
{
source: `/sitemap-:id(\\d{1,}).xml`,
destination: `/sitemap/:id`,
},
{
source: `/sitemap-index.xml`,
destination: `/sitemap`,
},
],
}
},
}
export default Sentry.withSentryConfig(nextConfig, {
org: "scandic-hotels",
project: "scandic-web",
authToken: process.env.SENTRY_AUTH_TOKEN,
// Only print logs for uploading source maps in CI
silent: !process.env.CI,
// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,
// Automatically annotate React components to show their full name in breadcrumbs and session replay
reactComponentAnnotation: {
enabled: true,
},
disableLogger: true,
})