fix: localize 404 and ensure header when no lang
This commit is contained in:
11
app/[lang]/(live)/middleware-error/404/page.tsx
Normal file
11
app/[lang]/(live)/middleware-error/404/page.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Lang } from "@/constants/languages"
|
||||
|
||||
import NotFound from "@/components/Current/NotFound"
|
||||
|
||||
import { LangParams, PageArgs } from "@/types/params"
|
||||
|
||||
export default function NotFoundPage({ params }: PageArgs<LangParams>) {
|
||||
const lang = params.lang || Lang.en
|
||||
|
||||
return <NotFound lang={lang} />
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
import { getIntl } from "@/i18n"
|
||||
import { headers } from "next/headers"
|
||||
|
||||
export default async function NotFound() {
|
||||
const { formatMessage } = await getIntl()
|
||||
return (
|
||||
<main>
|
||||
<h1>{formatMessage({ id: "Not found" })}</h1>
|
||||
<p>{formatMessage({ id: "Could not find requested resource" })}</p>
|
||||
</main>
|
||||
)
|
||||
import { Lang } from "@/constants/languages"
|
||||
|
||||
import NotFound from "@/components/Current/NotFound"
|
||||
|
||||
export default function NotFoundPage() {
|
||||
const headersList = headers()
|
||||
const lang = headersList.get("x-sh-language") as Lang
|
||||
|
||||
return <NotFound lang={lang} />
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ export default async function Header({
|
||||
lang,
|
||||
languageSwitcher,
|
||||
}: LangParams & { languageSwitcher: React.ReactNode }) {
|
||||
const data = await serverClient().contentstack.base.header()
|
||||
const data = await serverClient().contentstack.base.header({
|
||||
lang,
|
||||
})
|
||||
const session = await auth()
|
||||
|
||||
const homeHref = homeHrefs[env.NODE_ENV][lang]
|
||||
|
||||
131
components/Current/NotFound/Texts.ts
Normal file
131
components/Current/NotFound/Texts.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { Lang } from "@/constants/languages"
|
||||
|
||||
type Texts = {
|
||||
title: string
|
||||
goToStartPage: {
|
||||
question: string
|
||||
link: string
|
||||
linkText: string
|
||||
}
|
||||
goToDestinations: {
|
||||
question: string
|
||||
link: string
|
||||
linkText: string
|
||||
}
|
||||
goToOffers: {
|
||||
question: string
|
||||
link: string
|
||||
linkText: string
|
||||
}
|
||||
}
|
||||
|
||||
export const texts: Record<Lang, Texts> = {
|
||||
en: {
|
||||
title: "Sorry, page not found.",
|
||||
goToStartPage: {
|
||||
question: "Would you like to go back to the ",
|
||||
link: "https://www.scandichotels.com/",
|
||||
linkText: "startpage",
|
||||
},
|
||||
goToDestinations: {
|
||||
question: "Or take a trip to our ",
|
||||
link: "https://www.scandichotels.com/hotels",
|
||||
linkText: "destinations",
|
||||
},
|
||||
goToOffers: {
|
||||
question: " or latest ",
|
||||
link: "https://www.scandichotels.com/weekend-packages-and-offers",
|
||||
linkText: "offers",
|
||||
},
|
||||
},
|
||||
sv: {
|
||||
title: "Oj då, vi kunde inte hitta sidan du söker.",
|
||||
goToStartPage: {
|
||||
question: "Vill du gå tillbaka till ",
|
||||
link: "https://www.scandichotels.se/",
|
||||
linkText: "startsidan",
|
||||
},
|
||||
goToDestinations: {
|
||||
question: "Eller resa till våra ",
|
||||
link: "https://www.scandichotels.se/hotell",
|
||||
linkText: "destinationer",
|
||||
},
|
||||
goToOffers: {
|
||||
question: " eller se våra senaste ",
|
||||
link: "https://www.scandichotels.se/erbjudanden-och-weekendpaket",
|
||||
linkText: "erbjudanden",
|
||||
},
|
||||
},
|
||||
de: {
|
||||
title: "Tut uns leid, Seite nicht gefunden.",
|
||||
goToStartPage: {
|
||||
question: "Möchten Sie zurück zur ",
|
||||
link: "https://www.scandichotels.de/",
|
||||
linkText: "Startseite",
|
||||
},
|
||||
goToDestinations: {
|
||||
question: "Oder machen Sie einen Ausflug zu unseren ",
|
||||
link: "https://www.scandichotels.de/hotelsuche",
|
||||
linkText: "Reisezielen",
|
||||
},
|
||||
goToOffers: {
|
||||
question: " und aktuellen ",
|
||||
link: "https://www.scandichotels.de/angebote-arrangements",
|
||||
linkText: "Angeboten",
|
||||
},
|
||||
},
|
||||
fi: {
|
||||
title: "TValitettavasti sivua ei löydy.",
|
||||
goToStartPage: {
|
||||
question: "Haluaisitko mennä takaisin ",
|
||||
link: "https://www.scandichotels.fi/",
|
||||
linkText: "etusivulle",
|
||||
},
|
||||
goToDestinations: {
|
||||
question: "Voit myös tutustu ",
|
||||
link: "https://www.scandichotels.fi/hotellit",
|
||||
linkText: "kohteisiimme",
|
||||
},
|
||||
goToOffers: {
|
||||
question: " tai ajankohtaisiin ",
|
||||
link: "https://www.scandichotels.fi/tarjoukset",
|
||||
linkText: "tarjouksiimme",
|
||||
},
|
||||
},
|
||||
no: {
|
||||
title: "Oi da, vi fant ikke siden du lette etter...",
|
||||
goToStartPage: {
|
||||
question: "Vil du gå tilbake til ",
|
||||
link: "https://www.scandichotels.no/",
|
||||
linkText: "startsiden",
|
||||
},
|
||||
goToDestinations: {
|
||||
question: "Eller ta en tur til våre ",
|
||||
link: "https://www.scandichotels.no/hotell",
|
||||
linkText: "destinasjoner",
|
||||
},
|
||||
goToOffers: {
|
||||
question: " eller siste ",
|
||||
link: "https://www.scandichotels.no/hotelltilbud",
|
||||
linkText: "tilbud",
|
||||
},
|
||||
},
|
||||
da: {
|
||||
title: "Hov - siden kan ikke findes!",
|
||||
goToStartPage: {
|
||||
question: "Vil du gå tilbage til ",
|
||||
link: "https://www.scandichotels.dk/",
|
||||
linkText: "startsiden",
|
||||
},
|
||||
goToDestinations: {
|
||||
question: "Eller tag en tur til vores ",
|
||||
link: "https://www.scandichotels.dk/hoteller",
|
||||
linkText: "destinationer",
|
||||
},
|
||||
goToOffers: {
|
||||
question: " eller seneste ",
|
||||
link: "https://www.scandichotels.dk/tilbud-og-hotelpakker",
|
||||
linkText: "tilbud",
|
||||
},
|
||||
},
|
||||
}
|
||||
48
components/Current/NotFound/index.tsx
Normal file
48
components/Current/NotFound/index.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { texts } from "./Texts"
|
||||
|
||||
import styles from "./notFound.module.css"
|
||||
|
||||
import { LangParams } from "@/types/params"
|
||||
|
||||
export default function NotFound({ lang }: LangParams) {
|
||||
const infoTexts = texts[lang]
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
<h1 className={styles.header}>{infoTexts.title}</h1>
|
||||
<div className={styles.pitch}>
|
||||
<p className={styles.text}>
|
||||
{infoTexts.goToStartPage.question}
|
||||
<a
|
||||
className={styles.link}
|
||||
title={infoTexts.goToStartPage.linkText}
|
||||
href={infoTexts.goToStartPage.link}
|
||||
>
|
||||
{infoTexts.goToStartPage.linkText}
|
||||
</a>
|
||||
?
|
||||
</p>
|
||||
<p className={styles.text}>
|
||||
{infoTexts.goToDestinations.question}
|
||||
<a
|
||||
className={styles.link}
|
||||
title={infoTexts.goToDestinations.linkText}
|
||||
href={infoTexts.goToDestinations.link}
|
||||
>
|
||||
{infoTexts.goToDestinations.linkText}
|
||||
</a>
|
||||
{infoTexts.goToOffers.question}
|
||||
<a
|
||||
className={styles.link}
|
||||
title={infoTexts.goToOffers.linkText}
|
||||
href={infoTexts.goToOffers.link}
|
||||
>
|
||||
{infoTexts.goToOffers.linkText}
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
70
components/Current/NotFound/notFound.module.css
Normal file
70
components/Current/NotFound/notFound.module.css
Normal file
@@ -0,0 +1,70 @@
|
||||
.container {
|
||||
margin-top: 0;
|
||||
background: var(--Main-Grey-White);
|
||||
position: relative;
|
||||
border-top: 50px solid var(--Main-Grey-White);
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
box-sizing: content-box;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 70px 30px;
|
||||
}
|
||||
|
||||
.header {
|
||||
font-family:
|
||||
brandon text,
|
||||
Arial,
|
||||
Helvetica,
|
||||
sans-serif;
|
||||
font-size: 32px;
|
||||
line-height: 1;
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
font-weight: 400;
|
||||
color: #483729;
|
||||
}
|
||||
|
||||
.pitch {
|
||||
margin-top: 32px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-family:
|
||||
Helvetica Neue,
|
||||
Roboto,
|
||||
Helvetica,
|
||||
Arial,
|
||||
sans-serif;
|
||||
font-weight: 300;
|
||||
line-height: normal;
|
||||
text-transform: none;
|
||||
font-size: 20px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: #00838e;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 740px) {
|
||||
.content {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 950px) {
|
||||
.header {
|
||||
font-size: 46px;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NextMiddleware, NextResponse } from "next/server"
|
||||
|
||||
import { findLang } from "./constants/languages"
|
||||
import { findLang, Lang } from "./constants/languages"
|
||||
import * as authRequired from "./middlewares/authRequired"
|
||||
import * as cmsContent from "./middlewares/cmsContent"
|
||||
import * as currentWebLogin from "./middlewares/currentWebLogin"
|
||||
@@ -16,8 +16,10 @@ export const middleware: NextMiddleware = async (request, event) => {
|
||||
// Without it we shortcircuit early.
|
||||
// We use middleware-error route because notFound() requires a root layout
|
||||
// which we do not want. We can move to that once all Current stuff is gone.
|
||||
|
||||
// Default to English if no lang is found.
|
||||
return NextResponse.rewrite(
|
||||
new URL(`/${lang}/middleware-error/404`, request.nextUrl),
|
||||
new URL(`/${Lang.en}/middleware-error/404`, request.nextUrl),
|
||||
{
|
||||
status: 404,
|
||||
statusText: "Not found",
|
||||
|
||||
5
server/routers/contentstack/base/input.ts
Normal file
5
server/routers/contentstack/base/input.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
|
||||
export const headerInput = z.object({ lang: z.nativeEnum(Lang) })
|
||||
Reference in New Issue
Block a user