diff --git a/.npmrc b/.npmrc index 6c59086..9f7e8f9 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ enable-pre-post-scripts=true +legacy-peer-deps=true diff --git a/app/[locale]/404/page.tsx b/app/[locale]/404/page.tsx index 396d792..39f7562 100644 --- a/app/[locale]/404/page.tsx +++ b/app/[locale]/404/page.tsx @@ -1,14 +1,14 @@ import { ArrowRightIcon } from '@heroicons/react/24/outline'; -import { getTranslations, unstable_setRequestLocale } from 'next-intl/server'; +import { getTranslations, setRequestLocale } from 'next-intl/server'; import ButtonLink from '~/components/Common/Button/Link/index.tsx'; import styles from './page.module.css'; import type { FC } from 'react'; import type { Metadata } from 'next'; import type { BaseParams } from '~/types/params.ts'; -type NotFoundProps = { - params: BaseParams; -}; +type NotFoundProps = BaseParams; + +export const dynamic = 'force-static'; export const generateMetadata = async (): Promise => { const t = await getTranslations('app.notFound'); @@ -20,7 +20,8 @@ export const generateMetadata = async (): Promise => { }; const NotFound: FC = async ({ params }) => { - unstable_setRequestLocale(params.locale); + const { locale } = await params; + setRequestLocale(locale); const t = await getTranslations('app.notFound'); return ( @@ -35,6 +36,4 @@ const NotFound: FC = async ({ params }) => { ); }; -export const dynamic = 'error'; - export default NotFound; diff --git a/app/[locale]/about/page.tsx b/app/[locale]/about/page.tsx index 6610b8d..5424b01 100644 --- a/app/[locale]/about/page.tsx +++ b/app/[locale]/about/page.tsx @@ -8,16 +8,16 @@ import type { Metadata } from 'next'; import type { AboutFrontmatter } from '~/types/frontmatter.ts'; import type { BaseParams } from '~/types/params.ts'; -type PageProps = { - params: BaseParams; -}; +type PageProps = BaseParams; + +export const dynamic = 'force-static'; export const generateMetadata = async ({ params, }: PageProps): Promise => { const rawSource = await getContent({ section: 'about', - lang: params.locale, + lang: (await params).locale, }); if (!rawSource) return null; @@ -36,7 +36,7 @@ export const generateMetadata = async ({ const Page: FC = async ({ params }) => { const rawSource = await getContent({ section: 'about', - lang: params.locale, + lang: (await params).locale, }); if (!rawSource) notFound(); diff --git a/app/[locale]/blog/[[...page]]/page.tsx b/app/[locale]/blog/[[...page]]/page.tsx index 2e16c32..643467d 100644 --- a/app/[locale]/blog/[[...page]]/page.tsx +++ b/app/[locale]/blog/[[...page]]/page.tsx @@ -15,10 +15,10 @@ import type { BaseParams } from '~/types/params.ts'; const MAX_POSTS_PER_PAGE = 6; type PageProps = { - params: { + params: Promise<{ page?: string[]; - } & BaseParams; -}; + }>; +} & BaseParams; type StaticParams = { params: { @@ -26,6 +26,8 @@ type StaticParams = { }; }; +export const dynamic = 'force-static'; + export const generateMetadata = async (): Promise => { const t = await getTranslations('app.blog'); @@ -47,16 +49,20 @@ export const generateStaticParams = async ({ params }: StaticParams) => { }; const Page: FC = async ({ params }) => { + const { page, locale } = await params; let pageNumbers = null; - if (params.page && params.page[0] === 'index') { + if (page && page[0] === 'index') { pageNumbers = 0; - } else if (params.page && Number.isInteger(parseInt(params.page[0], 10))) { - pageNumbers = parseInt(params.page[0], 10); + } else if (page && Number.isInteger(parseInt(page[0], 10))) { + pageNumbers = parseInt(page[0], 10); } if (pageNumbers === null) notFound(); - const posts = await getSlugs({ section: 'blog', lang: params.locale }); + const posts = await getSlugs({ + section: 'blog', + lang: (await params).locale, + }); const metadata = await Promise.all( posts .slice( @@ -66,7 +72,7 @@ const Page: FC = async ({ params }) => { .map(slug => getFrontmatter({ section: 'blog', - lang: params.locale, + lang: locale, slug, }) ) diff --git a/app/[locale]/blog/post/[post]/page.tsx b/app/[locale]/blog/post/[post]/page.tsx index b84e0a6..67cb34b 100644 --- a/app/[locale]/blog/post/[post]/page.tsx +++ b/app/[locale]/blog/post/[post]/page.tsx @@ -9,10 +9,8 @@ import type { Metadata } from 'next'; import type { BlogFrontmatter } from '~/types/frontmatter.ts'; import type { BaseParams } from '~/types/params.ts'; -type PageProps = { - params: { - post: string; - } & BaseParams; +type PageProps = BaseParams & { + params: Promise<{ post: string }>; }; const slugToParams = (slug: string) => { @@ -26,8 +24,8 @@ export const generateMetadata = async ({ }: PageProps): Promise => { const rawSource = await getContent({ section: 'blog', - lang: params.locale, - slug: params.post, + lang: (await params).locale, + slug: (await params).post, }); if (!rawSource) return null; @@ -57,8 +55,8 @@ export const generateStaticParams = async () => { const Page: FC = async ({ params }) => { const rawSource = await getContent({ section: 'blog', - slug: params.post, - lang: params.locale, + slug: (await params).post, + lang: (await params).locale, }); if (!rawSource) notFound(); diff --git a/app/[locale]/feed/blog/rss.xml/route.ts b/app/[locale]/feed/blog/rss.xml/route.ts index f65cab7..b47d5bc 100644 --- a/app/[locale]/feed/blog/rss.xml/route.ts +++ b/app/[locale]/feed/blog/rss.xml/route.ts @@ -1,21 +1,19 @@ import { generateRssFeed } from '~/lib/rss.ts'; -import { availableLocales } from '~/utils/i18n/index.ts'; +import { availableLocales } from '~/lib/i18n/config.ts'; import type { BaseParams } from '~/types/params.ts'; +export const dynamic = 'force-static'; + export const generateStaticParams = () => { return availableLocales.map(lang => ({ locale: lang.code, })); }; -type GETProps = { - params: BaseParams; -}; - -export const GET = async (_: Request, { params }: GETProps) => { +export const GET = async (_: Request, { params }: BaseParams) => { const feed = await generateRssFeed({ section: 'blog', - lang: params.locale, + lang: (await params).locale, }); return new Response(feed, { diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx index 993d3d6..2c4f4e2 100644 --- a/app/[locale]/layout.tsx +++ b/app/[locale]/layout.tsx @@ -1,25 +1,23 @@ -import { getTranslations, unstable_setRequestLocale } from 'next-intl/server'; +import { getTranslations, setRequestLocale } from 'next-intl/server'; import classNames from 'classnames'; import { GeistSans } from 'geist/font/sans'; import { GeistMono } from 'geist/font/mono'; import { LocaleProvider } from '~/providers/localeProvider.tsx'; -import { availableLocales } from '~/utils/i18n/index.ts'; +import { routing } from '~/lib/i18n/routing'; import type { FC, PropsWithChildren } from 'react'; import type { Metadata } from 'next'; import type { BaseParams } from '~/types/params.ts'; import '~/styles/globals.css'; -type RootLayoutProps = PropsWithChildren<{ - params: BaseParams; -}>; +type RootLayoutProps = PropsWithChildren; -export const generateStaticParams = () => { - return availableLocales.map(lang => ({ - locale: lang.code, - })); -}; +export const dynamic = 'force-static'; + +// Generate params for all available locales +// It's allow us to build the website statically for all locales +export const generateStaticParams = () => + routing.locales.map(locale => ({ locale })); -// @TODO: Generate metadata using i18n export const generateMetadata = async (): Promise => { const t = await getTranslations('app.metadata'); @@ -28,13 +26,15 @@ export const generateMetadata = async (): Promise => { description: t('description'), }; }; -const RootLayout: FC = ({ children, params }) => { - unstable_setRequestLocale(params.locale); + +const RootLayout: FC = async ({ children, params }) => { + const { locale } = await params; + setRequestLocale(locale); return ( - + - {children} + {children} ); diff --git a/app/[locale]/projects/page.tsx b/app/[locale]/projects/page.tsx index 7b64646..28695df 100644 --- a/app/[locale]/projects/page.tsx +++ b/app/[locale]/projects/page.tsx @@ -8,16 +8,16 @@ import type { Metadata } from 'next'; import type { ProjectsFrontmatter } from '~/types/frontmatter.ts'; import type { BaseParams } from '~/types/params.ts'; -type PageProps = { - params: BaseParams; -}; +type PageProps = BaseParams; + +export const dynamic = 'force-static'; export const generateMetadata = async ({ params, }: PageProps): Promise => { const rawSource = await getContent({ section: 'projects', - lang: params.locale, + lang: (await params).locale, }); if (!rawSource) return null; @@ -36,7 +36,7 @@ export const generateMetadata = async ({ const Page: FC = async ({ params }) => { const rawSource = await getContent({ section: 'projects', - lang: params.locale, + lang: (await params).locale, }); if (!rawSource) notFound(); diff --git a/app/robots.ts b/app/robots.ts index 31eba49..18b3b57 100644 --- a/app/robots.ts +++ b/app/robots.ts @@ -1,6 +1,8 @@ import type { MetadataRoute } from 'next'; -function robots(): MetadataRoute.Robots { +export const dynamic = 'force-static'; + +export default function robots(): MetadataRoute.Robots { return { rules: { userAgent: '*', @@ -10,5 +12,3 @@ function robots(): MetadataRoute.Robots { sitemap: 'https://augustinmauroy.github.io/sitemap.xml', }; } - -export default robots; diff --git a/app/sitemap.ts b/app/sitemap.ts index 068910c..65d8337 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -1,7 +1,9 @@ import { generateSitemap } from '~/lib/sitemap'; -import { availableLocaleCodes } from '~/utils/i18n/index.ts'; +import { availableLocaleCodes } from '~/lib/i18n/config.ts'; import type { MetadataRoute } from 'next'; +export const dynamic = 'force-static'; + export default async function sitemap(): Promise { const sitemapEntries: MetadataRoute.Sitemap = []; diff --git a/components/Common/LanguageSelector/index.tsx b/components/Common/LanguageSelector/index.tsx index 6b733b3..776e8f2 100644 --- a/components/Common/LanguageSelector/index.tsx +++ b/components/Common/LanguageSelector/index.tsx @@ -3,12 +3,12 @@ import { LanguageIcon } from '@heroicons/react/24/outline'; import { useTranslations } from 'next-intl'; import { useParams, usePathname, useRouter } from 'next/navigation'; import Dropdown from '~/components/Common/Dropdown'; -import { availableLocales } from '~/utils/i18n'; +import { availableLocales } from '~/lib/i18n/config.ts'; const LanguageSelector = () => { const router = useRouter(); const pathname = usePathname(); - const locale = useParams().locale; + const locale = useParams().locale ?? 'en'; const t = useTranslations('components.common.languageSelector'); const handleLocaleChange = (newLocale: string) => { diff --git a/utils/i18n/index.ts b/lib/i18n/config.ts similarity index 82% rename from utils/i18n/index.ts rename to lib/i18n/config.ts index 65e970c..07d1070 100644 --- a/utils/i18n/index.ts +++ b/lib/i18n/config.ts @@ -1,4 +1,4 @@ -import localeConfig from '~/i18n/config.json' with { type: 'json' }; +import localeConfig from '~/i18n/config.json' assert { type: 'json' }; // As set of available and enabled locales for the website // This is used for allowing us to redirect the user to any @@ -10,7 +10,8 @@ const availableLocaleCodes = availableLocales.map(locale => locale.code); // This provides the default locale information for the Next.js Application // This is marked by the unique `locale.default` property on the `en` locale -const defaultLocale = availableLocales.find(locale => locale.default); +const defaultLocale = + availableLocales.find(locale => locale.default) || availableLocales[0]; // Creates a Map of available locales for easy access const availableLocalesMap = Object.fromEntries( diff --git a/utils/i18n/config.ts b/lib/i18n/request.ts similarity index 59% rename from utils/i18n/config.ts rename to lib/i18n/request.ts index d78f78c..2e0579e 100644 --- a/utils/i18n/config.ts +++ b/lib/i18n/request.ts @@ -1,5 +1,6 @@ import { getRequestConfig } from 'next-intl/server'; -import { availableLocaleCodes } from './index.ts'; +import { routing } from './routing.ts'; +import { availableLocaleCodes } from './config.ts'; // Loads the Application Locales/Translations Dynamically const loadLocaleDictionary = async (locale: string) => { @@ -18,10 +19,18 @@ const loadLocaleDictionary = async (locale: string) => { throw new Error(`Unsupported locale: ${locale}`); }; -// Provides `next-intl` configuration for RSC/SSR -export default getRequestConfig(async ({ locale }) => ({ - // This is the dictionary of messages to be loaded - messages: await loadLocaleDictionary(locale), - // We always define the App timezone as UTC - timeZone: 'Etc/UTC', -})); +export default getRequestConfig(async ({ requestLocale }) => { + // This typically corresponds to the `[locale]` segment + let locale = await requestLocale; + + // Ensure that the incoming locale is valid + if (!locale || !routing.locales.includes(locale)) + locale = routing.defaultLocale; + + const messages = await loadLocaleDictionary(locale); + + return { + locale, + messages, + }; +}); diff --git a/lib/i18n/routing.ts b/lib/i18n/routing.ts new file mode 100644 index 0000000..8aace2f --- /dev/null +++ b/lib/i18n/routing.ts @@ -0,0 +1,11 @@ +import { createNavigation } from 'next-intl/navigation'; +import { defineRouting } from 'next-intl/routing'; +import { availableLocaleCodes, defaultLocale } from './config.ts'; + +export const routing = defineRouting({ + locales: availableLocaleCodes, + defaultLocale: defaultLocale.code, +}); + +export const { Link, redirect, usePathname, useRouter } = + createNavigation(routing); diff --git a/lib/sitemap.ts b/lib/sitemap.ts index 4cae98d..9711ad8 100644 --- a/lib/sitemap.ts +++ b/lib/sitemap.ts @@ -1,4 +1,4 @@ -import { availableLocaleCodes } from '~/utils/i18n/index.ts'; +import { availableLocaleCodes } from './i18n/config.ts'; import { getSlugs, getFrontmatter } from './content.ts'; import type { MetadataRoute } from 'next'; import type { BlogFrontmatter } from '~/types/frontmatter.ts'; diff --git a/next.config.js b/next.config.js deleted file mode 100644 index 4a16529..0000000 --- a/next.config.js +++ /dev/null @@ -1,19 +0,0 @@ -import withNextIntl from 'next-intl/plugin'; - -/** @type {import('next').NextConfig} */ -const nextConfig = { - output: 'export', - transpilePackages: ['geist'], - images: { unoptimized: true }, - trailingSlash: false, - typescript: { - ignoreBuildErrors: true, - }, - eslint: { - ignoreDuringBuilds: true, - }, -}; - -const nextWithIntl = withNextIntl('./utils/i18n/config.ts')(nextConfig); - -export default nextWithIntl; diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..b4ad61b --- /dev/null +++ b/next.config.ts @@ -0,0 +1,21 @@ +import createNextIntlPlugin from 'next-intl/plugin'; +import type { NextConfig } from 'next'; + +const withNextIntl = createNextIntlPlugin('./lib/i18n/request.ts'); + +const nextConfig: NextConfig = { + // need to be test on CI but not on building of the app + typescript: { + ignoreBuildErrors: true, + }, + eslint: { + ignoreDuringBuilds: true, + }, + // Static website output + output: 'export', + images: { unoptimized: true }, + trailingSlash: false, + transpilePackages: ['geist', 'next-mdx-remote'], +}; + +export default withNextIntl(nextConfig); diff --git a/package-lock.json b/package-lock.json index a30665a..6a53557 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,8 @@ "classnames": "~2.5.1", "feed": "~4.2.2", "geist": "~1.3.1", - "next": "~14.2.13", - "next-intl": "~3.19.4", + "next": "~15.0.3", + "next-intl": "~3.25.3", "next-mdx-remote": "~5.0.0", "react": "~18.3.1", "react-dom": "~18.3.1", @@ -2716,52 +2716,53 @@ "license": "MIT" }, "node_modules/@formatjs/ecma402-abstract": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz", - "integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz", + "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==", "license": "MIT", "dependencies": { - "@formatjs/intl-localematcher": "0.5.4", - "tslib": "^2.4.0" + "@formatjs/fast-memoize": "2.2.3", + "@formatjs/intl-localematcher": "0.5.8", + "tslib": "2" } }, "node_modules/@formatjs/fast-memoize": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz", - "integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz", + "integrity": "sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==", "license": "MIT", "dependencies": { - "tslib": "^2.4.0" + "tslib": "2" } }, "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.7.8", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz", - "integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz", + "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.0.0", - "@formatjs/icu-skeleton-parser": "1.8.2", - "tslib": "^2.4.0" + "@formatjs/ecma402-abstract": "2.2.4", + "@formatjs/icu-skeleton-parser": "1.8.8", + "tslib": "2" } }, "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz", - "integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==", + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz", + "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.0.0", - "tslib": "^2.4.0" + "@formatjs/ecma402-abstract": "2.2.4", + "tslib": "2" } }, "node_modules/@formatjs/intl-localematcher": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz", - "integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz", + "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==", "license": "MIT", "dependencies": { - "tslib": "^2.4.0" + "tslib": "2" } }, "node_modules/@heroicons/react": { @@ -3323,15 +3324,15 @@ } }, "node_modules/@next/env": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.13.tgz", - "integrity": "sha512-s3lh6K8cbW1h5Nga7NNeXrbe0+2jIIYK9YaA9T7IufDWnZpozdFUp6Hf0d5rNWUKu4fEuSX2rCKlGjCrtylfDw==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.0.3.tgz", + "integrity": "sha512-t9Xy32pjNOvVn2AS+Utt6VmyrshbpfUMhIjFO60gI58deSo/KgLOp31XZ4O+kY/Is8WAGYwA5gR7kOb1eORDBA==", "license": "MIT" }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.13.tgz", - "integrity": "sha512-IkAmQEa2Htq+wHACBxOsslt+jMoV3msvxCn0WFSfJSkv/scy+i/EukBKNad36grRxywaXUYJc9mxEGkeIs8Bzg==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.3.tgz", + "integrity": "sha512-s3Q/NOorCsLYdCKvQlWU+a+GeAd3C8Rb3L1YnetsgwXzhc3UTWrtQpB/3eCjFOdGUj5QmXfRak12uocd1ZiiQw==", "cpu": [ "arm64" ], @@ -3345,9 +3346,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.13.tgz", - "integrity": "sha512-Dv1RBGs2TTjkwEnFMVL5XIfJEavnLqqwYSD6LXgTPdEy/u6FlSrLBSSfe1pcfqhFEXRAgVL3Wpjibe5wXJzWog==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.3.tgz", + "integrity": "sha512-Zxl/TwyXVZPCFSf0u2BNj5sE0F2uR6iSKxWpq4Wlk/Sv9Ob6YCKByQTkV2y6BCic+fkabp9190hyrDdPA/dNrw==", "cpu": [ "x64" ], @@ -3361,9 +3362,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.13.tgz", - "integrity": "sha512-yB1tYEFFqo4ZNWkwrJultbsw7NPAAxlPXURXioRl9SdW6aIefOLS+0TEsKrWBtbJ9moTDgU3HRILL6QBQnMevg==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.3.tgz", + "integrity": "sha512-T5+gg2EwpsY3OoaLxUIofmMb7ohAUlcNZW0fPQ6YAutaWJaxt1Z1h+8zdl4FRIOr5ABAAhXtBcpkZNwUcKI2fw==", "cpu": [ "arm64" ], @@ -3377,9 +3378,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.13.tgz", - "integrity": "sha512-v5jZ/FV/eHGoWhMKYrsAweQ7CWb8xsWGM/8m1mwwZQ/sutJjoFaXchwK4pX8NqwImILEvQmZWyb8pPTcP7htWg==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.3.tgz", + "integrity": "sha512-WkAk6R60mwDjH4lG/JBpb2xHl2/0Vj0ZRu1TIzWuOYfQ9tt9NFsIinI1Epma77JVgy81F32X/AeD+B2cBu/YQA==", "cpu": [ "arm64" ], @@ -3393,9 +3394,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.13.tgz", - "integrity": "sha512-aVc7m4YL7ViiRv7SOXK3RplXzOEe/qQzRA5R2vpXboHABs3w8vtFslGTz+5tKiQzWUmTmBNVW0UQdhkKRORmGA==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.0.3.tgz", + "integrity": "sha512-gWL/Cta1aPVqIGgDb6nxkqy06DkwJ9gAnKORdHWX1QBbSZZB+biFYPFti8aKIQL7otCE1pjyPaXpFzGeG2OS2w==", "cpu": [ "x64" ], @@ -3409,9 +3410,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.13.tgz", - "integrity": "sha512-4wWY7/OsSaJOOKvMsu1Teylku7vKyTuocvDLTZQq0TYv9OjiYYWt63PiE1nTuZnqQ4RPvME7Xai+9enoiN0Wrg==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.0.3.tgz", + "integrity": "sha512-QQEMwFd8r7C0GxQS62Zcdy6GKx999I/rTO2ubdXEe+MlZk9ZiinsrjwoiBL5/57tfyjikgh6GOU2WRQVUej3UA==", "cpu": [ "x64" ], @@ -3425,9 +3426,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.13.tgz", - "integrity": "sha512-uP1XkqCqV2NVH9+g2sC7qIw+w2tRbcMiXFEbMihkQ8B1+V6m28sshBwAB0SDmOe0u44ne1vFU66+gx/28RsBVQ==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.3.tgz", + "integrity": "sha512-9TEp47AAd/ms9fPNgtgnT7F3M1Hf7koIYYWCMQ9neOwjbVWJsHZxrFbI3iEDJ8rf1TDGpmHbKxXf2IFpAvheIQ==", "cpu": [ "arm64" ], @@ -3440,26 +3441,10 @@ "node": ">= 10" } }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.13.tgz", - "integrity": "sha512-V26ezyjPqQpDBV4lcWIh8B/QICQ4v+M5Bo9ykLN+sqeKKBxJVDpEc6biDVyluTXTC40f5IqCU0ttth7Es2ZuMw==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.13.tgz", - "integrity": "sha512-WwzOEAFBGhlDHE5Z73mNU8CO8mqMNLqaG+AO9ETmzdCQlJhVtWZnOl2+rqgVQS+YHunjOWptdFmNfbpwcUuEsw==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.3.tgz", + "integrity": "sha512-VNAz+HN4OGgvZs6MOoVfnn41kBzT+M+tB+OK4cww6DNyWS6wKaDpaAm/qLeOUbnMh0oVx1+mg0uoYARF69dJyA==", "cpu": [ "x64" ], @@ -5026,12 +5011,11 @@ "license": "Apache-2.0" }, "node_modules/@swc/helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", - "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", + "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", "license": "Apache-2.0", "dependencies": { - "@swc/counter": "^0.1.3", "tslib": "^2.4.0" } }, @@ -5466,6 +5450,7 @@ "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "dev": true, "license": "MIT" }, "node_modules/@types/qs": { @@ -5486,6 +5471,7 @@ "version": "18.3.8", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.8.tgz", "integrity": "sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==", + "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -5496,7 +5482,7 @@ "version": "18.3.0", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@types/react": "*" @@ -5850,6 +5836,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -7272,7 +7259,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -7287,7 +7273,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -7300,14 +7286,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/color-string": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -7674,6 +7659,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, "license": "MIT" }, "node_modules/data-urls": { @@ -7855,7 +7841,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, "license": "Apache-2.0", "optional": true, "engines": { @@ -9241,6 +9226,7 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, "license": "ISC" }, "node_modules/has-flag": { @@ -9871,15 +9857,15 @@ "license": "MIT" }, "node_modules/intl-messageformat": { - "version": "10.5.14", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.14.tgz", - "integrity": "sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w==", + "version": "10.7.7", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.7.tgz", + "integrity": "sha512-F134jIoeYMro/3I0h08D0Yt4N9o9pjddU/4IIxMMURqbAtI2wu70X8hvG1V48W49zXHXv3RKSF/po+0fDfsGjA==", "license": "BSD-3-Clause", "dependencies": { - "@formatjs/ecma402-abstract": "2.0.0", - "@formatjs/fast-memoize": "2.2.0", - "@formatjs/icu-messageformat-parser": "2.7.8", - "tslib": "^2.4.0" + "@formatjs/ecma402-abstract": "2.2.4", + "@formatjs/fast-memoize": "2.2.3", + "@formatjs/icu-messageformat-parser": "2.9.4", + "tslib": "2" } }, "node_modules/invariant": { @@ -12020,6 +12006,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -12033,41 +12020,42 @@ "license": "MIT" }, "node_modules/next": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.13.tgz", - "integrity": "sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/next/-/next-15.0.3.tgz", + "integrity": "sha512-ontCbCRKJUIoivAdGB34yCaOcPgYXr9AAkV/IwqFfWWTXEPUgLYkSkqBhIk9KK7gGmgjc64B+RdoeIDM13Irnw==", "license": "MIT", "dependencies": { - "@next/env": "14.2.13", - "@swc/helpers": "0.5.5", + "@next/env": "15.0.3", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.13", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", - "graceful-fs": "^4.2.11", "postcss": "8.4.31", - "styled-jsx": "5.1.1" + "styled-jsx": "5.1.6" }, "bin": { "next": "dist/bin/next" }, "engines": { - "node": ">=18.17.0" + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.13", - "@next/swc-darwin-x64": "14.2.13", - "@next/swc-linux-arm64-gnu": "14.2.13", - "@next/swc-linux-arm64-musl": "14.2.13", - "@next/swc-linux-x64-gnu": "14.2.13", - "@next/swc-linux-x64-musl": "14.2.13", - "@next/swc-win32-arm64-msvc": "14.2.13", - "@next/swc-win32-ia32-msvc": "14.2.13", - "@next/swc-win32-x64-msvc": "14.2.13" + "@next/swc-darwin-arm64": "15.0.3", + "@next/swc-darwin-x64": "15.0.3", + "@next/swc-linux-arm64-gnu": "15.0.3", + "@next/swc-linux-arm64-musl": "15.0.3", + "@next/swc-linux-x64-gnu": "15.0.3", + "@next/swc-linux-x64-musl": "15.0.3", + "@next/swc-win32-arm64-msvc": "15.0.3", + "@next/swc-win32-x64-msvc": "15.0.3", + "sharp": "^0.33.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-66855b96-20241106", + "react-dom": "^18.2.0 || 19.0.0-rc-66855b96-20241106", "sass": "^1.3.0" }, "peerDependenciesMeta": { @@ -12077,15 +12065,18 @@ "@playwright/test": { "optional": true }, + "babel-plugin-react-compiler": { + "optional": true + }, "sass": { "optional": true } } }, "node_modules/next-intl": { - "version": "3.19.4", - "resolved": "https://registry.npmjs.org/next-intl/-/next-intl-3.19.4.tgz", - "integrity": "sha512-ywJZS+i+CEBYrZq5RXhoBLpjIQBzcVGWclb/CLUO6Lua+ECPM+uJVTb9WascBDT44bSaPcJT11+ZyaEuWEtlOA==", + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/next-intl/-/next-intl-3.25.3.tgz", + "integrity": "sha512-3VQ+OZdU9Z2enx5uWLYfmd/eb/gZN6QIfj59ROE/R+MTSD7ZAOPsGFnKqj5wwqm4EISGviYenkSuxypyYnhomA==", "funding": [ { "type": "individual", @@ -12095,12 +12086,21 @@ "license": "MIT", "dependencies": { "@formatjs/intl-localematcher": "^0.5.4", - "negotiator": "^0.6.3", - "use-intl": "^3.19.4" + "negotiator": "^1.0.0", + "use-intl": "^3.25.3" }, "peerDependencies": { - "next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0" + } + }, + "node_modules/next-intl/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, "node_modules/next-mdx-remote": { @@ -12152,29 +12152,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/next/node_modules/styled-jsx": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", - "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", - "license": "MIT", - "dependencies": { - "client-only": "0.0.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "babel-plugin-macros": { - "optional": true - } - } - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -14365,7 +14342,7 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, + "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -14502,7 +14479,6 @@ "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", - "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "optional": true, @@ -14612,7 +14588,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -14623,7 +14598,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true, "license": "MIT", "optional": true }, @@ -14998,7 +14972,6 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", - "dev": true, "license": "MIT", "dependencies": { "client-only": "0.0.1" @@ -16001,16 +15974,16 @@ } }, "node_modules/use-intl": { - "version": "3.19.4", - "resolved": "https://registry.npmjs.org/use-intl/-/use-intl-3.19.4.tgz", - "integrity": "sha512-mMUlie/zWiKfO8erR+17dCBL8tBsMWCadqfu/3fipzxVJ8XzZV477k6EBllXR/WfbamwwDFmb6RgYKhHDxGzYw==", + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/use-intl/-/use-intl-3.25.3.tgz", + "integrity": "sha512-zF+GHRx7auT1qpmiPMN+RnzSad6W5ZjhOpgC5Li/TByqCkMs4SP3xcd8C0jWxT8YI8Ucl518bnkS+gvKIvrXjw==", "license": "MIT", "dependencies": { "@formatjs/fast-memoize": "^2.2.0", "intl-messageformat": "^10.5.14" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0" } }, "node_modules/use-sidecar": { diff --git a/package.json b/package.json index a5a0b18..e6244d4 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "classnames": "~2.5.1", "feed": "~4.2.2", "geist": "~1.3.1", - "next": "~14.2.13", - "next-intl": "~3.19.4", + "next": "~15.0.3", + "next-intl": "~3.25.3", "next-mdx-remote": "~5.0.0", "react": "~18.3.1", "react-dom": "~18.3.1", diff --git a/types/params.ts b/types/params.ts index 0ee7f49..bd6c7d0 100644 --- a/types/params.ts +++ b/types/params.ts @@ -1,3 +1,8 @@ +/*export type BaseParams = { + params: Promise<{ locale: string }>; +};*/ +// add way to extend base params + export type BaseParams = { - locale: string; + params: Promise<{ locale: string }>; };