From 406ff44bb4b90ff74621d6359cfdbef3edb566a1 Mon Sep 17 00:00:00 2001 From: mauro-balades Date: Mon, 2 Sep 2024 20:51:56 +0200 Subject: [PATCH] refactor: Remove unnecessary output property in next.config.js --- next.config.js | 2 +- src/app/[locale]/layout.tsx | 23 +----- src/app/[locale]/not-found.tsx | 5 -- src/app/feed.xml/route.ts | 110 ----------------------------- src/app/layout.tsx | 14 ---- src/app/page.tsx | 7 -- src/components/locale-switcher.tsx | 3 +- src/i18n.ts | 19 ++--- src/i18n/routing.ts | 5 +- src/middleware.ts | 4 +- 10 files changed, 21 insertions(+), 171 deletions(-) delete mode 100644 src/app/feed.xml/route.ts delete mode 100644 src/app/layout.tsx delete mode 100644 src/app/page.tsx diff --git a/next.config.js b/next.config.js index 639cbcc..1a5f198 100644 --- a/next.config.js +++ b/next.config.js @@ -45,4 +45,4 @@ const nextConfig = (phase, { defaultConfig }) => { }; }; -module.exports = {...withNextIntl(nextConfig)}; +module.exports = withNextIntl(nextConfig); diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index e591c8d..c839634 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -4,11 +4,9 @@ import "./globals.css"; import { ThemeProvider } from "@/components/theme-provider"; import StyledComponentsRegistry from "@/lib/styled-components-registry"; import {NextIntlClientProvider} from 'next-intl'; -import {unstable_setRequestLocale} from 'next-intl/server'; import Footer from "@/components/footer"; import { Navigation } from "@/components/navigation"; -import { notFound } from "next/navigation"; -import {routing} from '@/i18n/routing'; +import { getMessages } from "next-intl/server"; const inter = Inter({ subsets: ["latin"] }); @@ -18,29 +16,14 @@ export const metadata: Metadata = { keywords: ["Zen", "Browser", "Zen Browser", "Web", "Internet", "Fast"], }; -const SUPPORTED_LANGUAGES = ["en", "de"]; - -async function getMessages(locale: string) { - try { - return (await import(`../../../messages/${locale}.json`)).default - } catch (error) { - notFound() - } -} - -export function generateStaticParams() { - return routing.locales.map((locale) => ({locale})); -} - export default async function RootLayout({ children, - params: {locale}, + params: {locale} }: Readonly<{ children: React.ReactNode; params: {locale: string}; }>) { - unstable_setRequestLocale(locale); - const messages = await getMessages(locale); + const messages = await getMessages(); return ( diff --git a/src/app/[locale]/not-found.tsx b/src/app/[locale]/not-found.tsx index d05717c..5855f54 100644 --- a/src/app/[locale]/not-found.tsx +++ b/src/app/[locale]/not-found.tsx @@ -1,8 +1,3 @@ -import { BrandingAssets } from "@/components/branding-assets"; -import Footer from "@/components/footer"; -import { Navigation } from "@/components/navigation"; - -export const runtime = 'edge' export default function NotFoundPage() { return ( diff --git a/src/app/feed.xml/route.ts b/src/app/feed.xml/route.ts deleted file mode 100644 index 4d761f1..0000000 --- a/src/app/feed.xml/route.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Feed } from "feed"; -import { releaseNotes } from "@/lib/release-notes"; -import type { ReleaseNote } from "@/lib/release-notes"; - -// Force feed.xml to be cached as static and remain constant for the lifetime of the current site build. -// The supplied releaseNotes array is constant per build, so this will always be the latest release notes. -export const dynamic = "force-static"; - -/** The default number of entries to include in the RSS feed. */ -const RSS_ENTRY_LIMIT = 20; - -/** - * Handles the GET request for the `feed.xml` endpoint. - * @returns The RSS feed for the Zen Browser release notes. - */ -export async function GET() { - // Just in case the release notes array is empty for whatever reason. - const latestDate = releaseNotes.length > 0 - ? formatRssDate(releaseNotes[0].date) - : new Date(); - - const feed = new Feed({ - id: "https://www.zen-browser.app/release-notes", - link: "https://www.zen-browser.app/release-notes", - title: "Zen Browser Release Notes", - description: "Release Notes for the Zen Browser", - language: "en", - favicon: "https://www.zen-browser.app/favicon.ico", - copyright: `Zen Browser © ${new Date().getFullYear()} - Made with ❤️ by the Zen team.`, - updated: latestDate, - }); - - for (const releaseNote of releaseNotes.slice(0, RSS_ENTRY_LIMIT)) { - feed.addItem({ - title: `Release notes for version ${releaseNote.version}`, - id: `https://www.zen-browser.app/release-notes/${releaseNote.version}`, - link: `https://www.zen-browser.app/release-notes/${releaseNote.version}`, - date: formatRssDate(releaseNote.date), - description: releaseNote.extra, - content: formatReleaseNote(releaseNote), - }); - } - - return new Response(feed.rss2(), { - headers: { - 'Content-Type': 'application/xml; charset=utf-8', - }, - }); -} - -/** - * Formats a date string in the format day/month/year. - * - * Note: If release notes change to ISO format, this will need to be updated. - * @param dateStr The date string to format. - * @returns The passed in date string as a Date object. - */ -function formatRssDate(dateStr: string) { - const splitDate = dateStr.split("/"); - if (splitDate.length !== 3) { - throw new Error("Invalid date format"); - } - - const day = Number(splitDate[0]); - const month = Number(splitDate[1]) - 1; - const year = Number(splitDate[2]); - return new Date(year, month, day); -} - -/** - * Formats the release note entry for use as the content of the RSS feed. - * @param releaseNote The release note to format. - * @returns The formatted release note as a HTML string. - */ -function formatReleaseNote(releaseNote: ReleaseNote) { - let content = "

If you encounter any issues, please report them on the issues page. Thanks everyone for your feedback! ❤️

"; - - if (releaseNote.extra) { - content += `

${releaseNote.extra.replace(/(\n)/g, "
")}

` - } - - if (releaseNote.breakingChanges) { - content += `

⚠️ Breaking changes

` - content += `` - } - - if (releaseNote.features) { - content += `

⭐ Features

` - content += `` - } - - if (releaseNote.fixes) { - content += `

✓ Fixes

` - content += `` - } - - return content; -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx deleted file mode 100644 index 05c5fd3..0000000 --- a/src/app/layout.tsx +++ /dev/null @@ -1,14 +0,0 @@ - -import {ReactNode} from 'react'; - - -type Props = { - children: ReactNode; -}; - - -// Since we have a `not-found.tsx` page on the root, a layout file -// is required, even if it's just passing children through. -export default function RootLayout({children}: Props) { - return children; -} \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx deleted file mode 100644 index 9594e6b..0000000 --- a/src/app/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ - -import {redirect} from 'next/navigation'; - - -export default function RootPage() { - redirect('/en'); -} \ No newline at end of file diff --git a/src/components/locale-switcher.tsx b/src/components/locale-switcher.tsx index 9c5bf4e..3b13242 100644 --- a/src/components/locale-switcher.tsx +++ b/src/components/locale-switcher.tsx @@ -1,7 +1,6 @@ "use client"; -import { usePathname, useRouter } from '@/i18n/routing'; +import { SUPPORTED_LANGUAGES, usePathname, useRouter } from '@/i18n/routing'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select'; -import { SUPPORTED_LANGUAGES } from '@/i18n'; export default function LocaleSwitcher() { const router = useRouter(); diff --git a/src/i18n.ts b/src/i18n.ts index 460b8fc..d603943 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -1,9 +1,12 @@ -import { getRequestConfig } from "next-intl/server"; - -export const SUPPORTED_LANGUAGES = ['en', 'de']; - +import {notFound} from 'next/navigation'; +import {getRequestConfig} from 'next-intl/server'; +import {routing} from './i18n/routing'; + export default getRequestConfig(async ({locale}) => { - const lang = SUPPORTED_LANGUAGES.includes(locale) ? locale : 'en'; - const messages = await import(`../messages/${lang}.json`); - return {messages}; -}); + // Validate that the incoming `locale` parameter is valid + if (!routing.locales.includes(locale as any)) notFound(); + + return { + messages: (await import(`../messages/${locale}.json`)).default + }; +}); \ No newline at end of file diff --git a/src/i18n/routing.ts b/src/i18n/routing.ts index 7c12c69..d4456d2 100644 --- a/src/i18n/routing.ts +++ b/src/i18n/routing.ts @@ -1,13 +1,14 @@ import {defineRouting} from 'next-intl/routing'; import {createSharedPathnamesNavigation} from 'next-intl/navigation'; -import { SUPPORTED_LANGUAGES } from '@/i18n'; +export const SUPPORTED_LANGUAGES = ['en', 'de']; export const routing = defineRouting({ // A list of all locales that are supported locales: SUPPORTED_LANGUAGES, // Used when no locale matches - defaultLocale: 'en' + defaultLocale: 'en', + localePrefix: "always", }); // Lightweight wrappers around Next.js' navigation APIs diff --git a/src/middleware.ts b/src/middleware.ts index e8bdd3f..789f2e0 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -4,6 +4,6 @@ import {routing} from './i18n/routing'; export default createMiddleware(routing); export const config = { - // Match only internationalized pathnames - matcher: ['/', '/(de|en)/:path*'] + // Match only internationalized pathnames and all paths that dont start with static + matcher: ['/', '/:path((?!_next|next|static).*)*'], }; \ No newline at end of file