From e5e2bf5bce2d44fe2f46cac416e51a40dab3ce1f Mon Sep 17 00:00:00 2001 From: Florian Trayon <26360935+FlorianLeChat@users.noreply.github.com> Date: Sat, 21 Dec 2024 20:08:15 +0100 Subject: [PATCH] Removed custom support for base path configuration with NextJS --- .eslintrc.json | 2 +- app/[locale]/components/cookie-consent.tsx | 5 +--- app/[locale]/components/notification.tsx | 20 ++++++------- app/[locale]/components/recaptcha.tsx | 2 +- app/[locale]/dashboard/actions/file-upload.ts | 2 +- .../dashboard/components/data-table.tsx | 6 ++-- .../dashboard/components/share-manager.tsx | 18 +++++------- app/[locale]/dashboard/page.tsx | 4 +-- app/[locale]/layout.tsx | 7 ++--- middleware.ts | 29 +++++-------------- next.config.ts | 1 - utilities/next-auth.ts | 8 ++--- 12 files changed, 36 insertions(+), 68 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 80af882..7602698 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -35,7 +35,7 @@ "space-in-parens": ["error", "always"], "no-param-reassign": ["error", { "props": false }], "operator-linebreak": ["error", "before", { "overrides": { "=": "after" } }], - "no-underscore-dangle": ["error", { "allow": ["_def", "_count", "__NEXT_ROUTER_BASEPATH"] }], // https://github.com/vercel/next.js/issues/52201#issuecomment-1620629437 + "no-underscore-dangle": ["error", { "allow": ["_def", "_count"] }], // https://github.com/vercel/next.js/issues/52201#issuecomment-1620629437 "object-curly-newline": ["error", { "ImportDeclaration": { "minProperties": 0 }}], "array-bracket-spacing": ["error", "always"], "template-curly-spacing": ["error", "always"], diff --git a/app/[locale]/components/cookie-consent.tsx b/app/[locale]/components/cookie-consent.tsx index 35b26b4..69fffc1 100644 --- a/app/[locale]/components/cookie-consent.tsx +++ b/app/[locale]/components/cookie-consent.tsx @@ -70,10 +70,7 @@ export default function CookieConsent() // Paramètres internes des cookies. cookie: { name: "NEXT_COOKIE", - path: - process.env.__NEXT_ROUTER_BASEPATH === "" - ? "/" - : process.env.__NEXT_ROUTER_BASEPATH + path: "/" }, // Paramètres de l'interface utilisateur. diff --git a/app/[locale]/components/notification.tsx b/app/[locale]/components/notification.tsx index b181046..532c866 100644 --- a/app/[locale]/components/notification.tsx +++ b/app/[locale]/components/notification.tsx @@ -40,8 +40,8 @@ export default function Notifications() const locale = useLocale(); const formMessages = useTranslations( "form" ); const modalMessages = useTranslations( "modals.notifications" ); - const [ isOpen, setOpen ] = useState( false ); - const [ isLoading, setLoading ] = useState( false ); + const [ isOpen, setIsOpen ] = useState( false ); + const [ isLoading, setIsLoading ] = useState( false ); const [ unreadCount, setUnreadCount ] = useState( 0 ); const [ notifications, setNotifications ] = useState( [] ); @@ -49,12 +49,10 @@ export default function Notifications() const fetchNotifications = useCallback( async () => { // Activation de l'état de chargement. - setLoading( true ); + setIsLoading( true ); // Lancement de la requête HTTP et vérification de la réponse. - const response = await fetch( - `${ process.env.__NEXT_ROUTER_BASEPATH }/api/user/notifications` - ); + const response = await fetch( "/api/user/notifications" ); if ( !response.ok ) { @@ -77,7 +75,7 @@ export default function Notifications() setUnreadCount( ( count ) => Math.min( data.length, count + filter.length ) ); // Désactivation de l'état de chargement. - setLoading( false ); + setIsLoading( false ); // Vérification de l'existence de l'API de notifications. if ( typeof Notification !== "undefined" && filter.length > 0 ) @@ -131,19 +129,19 @@ export default function Notifications() const submitClearing = async () => { // Activation de l'état de chargement. - setLoading( true ); + setIsLoading( true ); // Envoi de la requête au serveur et // traitement de la réponse. const state = await serverAction( updateReadState, new FormData(), formMessages ); // Fin de l'état de chargement. - setLoading( false ); + setIsLoading( false ); if ( state ) { // Fermeture de la boîte de dialogue. - setOpen( false ); + setIsOpen( false ); // Marquage de toutes les notifications // comme lues. @@ -190,7 +188,7 @@ export default function Notifications() { if ( !isLoading ) { - setOpen( state ); + setIsOpen( state ); } }} > diff --git a/app/[locale]/components/recaptcha.tsx b/app/[locale]/components/recaptcha.tsx index d77e489..90ec5d0 100644 --- a/app/[locale]/components/recaptcha.tsx +++ b/app/[locale]/components/recaptcha.tsx @@ -65,7 +65,7 @@ export default function Recaptcha() const body = new FormData(); body.append( "1_recaptcha", token ); - fetch( `${ process.env.__NEXT_ROUTER_BASEPATH }/api/recaptcha`, { + fetch( "/api/recaptcha", { body, method: "POST" } ); diff --git a/app/[locale]/dashboard/actions/file-upload.ts b/app/[locale]/dashboard/actions/file-upload.ts index c1c55c5..4d48538 100644 --- a/app/[locale]/dashboard/actions/file-upload.ts +++ b/app/[locale]/dashboard/actions/file-upload.ts @@ -294,7 +294,7 @@ export async function uploadFiles( // fichiers sous format JSON pour pouvoir les envoyer // à travers le réseau vers les composants clients. // Source : https://github.com/vercel/next.js/issues/47447 - const path = `${ process.env.__NEXT_ROUTER_BASEPATH }/d/${ fileId }${ + const path = `/d/${ fileId }${ preferences.extension ? extension : "" }`; const versions = await prisma.version.findMany( { diff --git a/app/[locale]/dashboard/components/data-table.tsx b/app/[locale]/dashboard/components/data-table.tsx index 8c0e726..a604ce0 100644 --- a/app/[locale]/dashboard/components/data-table.tsx +++ b/app/[locale]/dashboard/components/data-table.tsx @@ -35,7 +35,7 @@ import Pagination from "./pagination"; import FileUpload from "./file-upload"; import ColumnToggle from "./column-toggle"; -export default function DataTable( { data }: { data: FileAttributes[] } ) +export default function DataTable( { data }: Readonly<{ data: FileAttributes[] }> ) { // Déclaration des variables d'état. const messages = useMessages() as { @@ -117,9 +117,7 @@ export default function DataTable( { data }: { data: FileAttributes[] } ) // Affichage du rendu HTML du composant. return ( - + {/* Filtrage et tri des données */}
{/* Filtrage par nom */} diff --git a/app/[locale]/dashboard/components/share-manager.tsx b/app/[locale]/dashboard/components/share-manager.tsx index 9e7983a..78b4225 100644 --- a/app/[locale]/dashboard/components/share-manager.tsx +++ b/app/[locale]/dashboard/components/share-manager.tsx @@ -50,11 +50,11 @@ export default function ShareManager( { file, states, disabled -}: { +}: Readonly<{ file: FileAttributes; states: TableMeta; disabled: boolean; -} ) +}> ) { // Déclaration des constantes. const fetcher = ( url: string ) => fetch( url ).then( ( res ) => res.json() ) as Promise; @@ -63,14 +63,12 @@ export default function ShareManager( { const session = useSession(); const formMessages = useTranslations( "form" ); const modalMessages = useTranslations( "modals.share-manager" ); - const [ isOpen, setOpen ] = useState( false ); + const [ isOpen, setIsOpen ] = useState( false ); const [ search, setSearch ] = useState( "" ); const [ loading, setLoading ] = useState( false ); - const [ isCopied, setCopied ] = useState( false ); + const [ isCopied, setIsCopied ] = useState( false ); const { data, error, isLoading } = useSWR( - search !== "" - ? `${ process.env.__NEXT_ROUTER_BASEPATH }/api/user/search/${ search }` - : null, + search !== "" ? `/api/user/search/${ search }` : null, fetcher ); @@ -240,7 +238,7 @@ export default function ShareManager( { { if ( !loading ) { - setOpen( state ); + setIsOpen( state ); } }} > @@ -282,10 +280,10 @@ export default function ShareManager( { onClick={() => { // Déclaration de la copie du lien. - setCopied( true ); + setIsCopied( true ); // Réinitialisation de l'état de copie. - setTimeout( () => setCopied( false ), 1500 ); + setTimeout( () => setIsCopied( false ), 1500 ); // Copie du lien dans le presse-papiers. navigator.clipboard.writeText( diff --git a/app/[locale]/dashboard/page.tsx b/app/[locale]/dashboard/page.tsx index 1273969..7459f28 100644 --- a/app/[locale]/dashboard/page.tsx +++ b/app/[locale]/dashboard/page.tsx @@ -91,9 +91,7 @@ async function getFiles(): Promise files.map( async ( file ) => { const info = parse( file.name ); - const path = `${ process.env.__NEXT_ROUTER_BASEPATH }/d/${ file.id }${ - extension ? info.ext : "" - }`; + const path = `/d/${ file.id }${ extension ? info.ext : "" }`; return { uuid: file.id, diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx index 89c18b5..3cf1e52 100644 --- a/app/[locale]/layout.tsx +++ b/app/[locale]/layout.tsx @@ -91,10 +91,7 @@ export async function generateMetadata(): Promise< // On détermine après certaines métadonnées récurrentes. const banner = `https://opengraph.githubassets.com/${ commits.sha }/${ repository.full_name }`; const title = repository.name.replaceAll( "-", " " ); - const url = - process.env.NEXT_PUBLIC_ENV === "production" - ? repository.homepage - : `http://localhost:3000${ process.env.__NEXT_ROUTER_BASEPATH }`; + const url = process.env.NEXT_PUBLIC_ENV === "production" ? repository.homepage : "http://localhost:3000"; // On retourne également les métadonnées récupérées récemment // avant de les enregistrer dans un fichier JSON. @@ -312,7 +309,7 @@ export default async function Layout( { className="fixed -z-10 hidden size-full object-none opacity-10 dark:block" > diff --git a/middleware.ts b/middleware.ts index 40f6c10..f90e44b 100644 --- a/middleware.ts +++ b/middleware.ts @@ -36,7 +36,7 @@ export default async function middleware( request: NextRequest ) // du fichier à partir de son identifiant. const data = await fetch( new URL( - `${ process.env.__NEXT_ROUTER_BASEPATH }/api/file/${ identifier }/${ request.nextUrl.search }`, + `/api/file/${ identifier }/${ request.nextUrl.search }`, request.url ), { headers: request.headers } @@ -60,7 +60,7 @@ export default async function middleware( request: NextRequest ) const content = await fetch( new URL( - `${ process.env.__NEXT_ROUTER_BASEPATH }/api/public/files/${ file.userId }/${ file.id }/${ file.versions[ 0 ].id }.${ extension }`, + `/api/public/files/${ file.userId }/${ file.id }/${ file.versions[ 0 ].id }.${ extension }`, data.url ), { headers } @@ -152,13 +152,9 @@ export default async function middleware( request: NextRequest ) // des robots d'indexation. if ( request.nextUrl.pathname.startsWith( "/avatars/" ) ) { - const data = await fetch( - new URL( - `${ process.env.__NEXT_ROUTER_BASEPATH }/api/user/session`, - request.url - ), - { headers: request.headers } - ); + const data = await fetch( new URL( "/api/user/session", request.url ), { + headers: request.headers + } ); if ( data.ok ) { @@ -169,10 +165,7 @@ export default async function middleware( request: NextRequest ) headers.set( "X-Auth-Secret", process.env.AUTH_SECRET ?? "" ); const content = await fetch( - new URL( - `${ process.env.__NEXT_ROUTER_BASEPATH }/api/public/${ session.image }`, - data.url - ), + new URL( `/api/public/${ session.image }`, data.url ), { headers } ); @@ -266,12 +259,4 @@ export const config = { "/", "/((?!api/admin|api/user|api/version|api/versions|api/file|api/public|api/files|monitoring|assets|locales|_next|_vercel|sitemap.xml|manifest.webmanifest).*)" ] -}; - -if ( process.env.__NEXT_ROUTER_BASEPATH ) -{ - // Ajout du support du chemin de base de NextJS pour le routage - // effectué par le mécanisme de gestion des langues et traductions. - // Source : https://next-intl-docs.vercel.app/docs/routing/middleware#base-path - config.matcher.push( process.env.__NEXT_ROUTER_BASEPATH ); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/next.config.ts b/next.config.ts index 83bae70..907bead 100644 --- a/next.config.ts +++ b/next.config.ts @@ -14,7 +14,6 @@ const nextConfig: NextConfig = withNextIntl( { ) } }, - basePath: "", async redirects() { return [ diff --git a/utilities/next-auth.ts b/utilities/next-auth.ts index 50c1a51..5fd0567 100644 --- a/utilities/next-auth.ts +++ b/utilities/next-auth.ts @@ -29,9 +29,7 @@ export const { handlers, auth, signIn, signOut } = NextAuth( () => ( { session: { strategy: process.env.NEXT_PUBLIC_ENV === "production" ? "database" : "jwt" }, - basePath: process.env.AUTH_URL - ? undefined - : `${ process.env.__NEXT_ROUTER_BASEPATH }/api/user/auth`, + basePath: process.env.AUTH_URL ? undefined : "/api/user/auth", trustHost: true, callbacks: { // Gestion des données du jeton JWT (environnement de test et de développement). @@ -85,7 +83,7 @@ export const { handlers, auth, signIn, signOut } = NextAuth( () => ( { if ( avatar.find( ( file ) => file.includes( token.id ) ) ) { // Définition de l'avatar personnalisé de l'utilisateur. - token.image = `${ process.env.__NEXT_ROUTER_BASEPATH }/avatars/${ avatar }`; + token.image = `/avatars/${ avatar }`; } } } @@ -139,7 +137,7 @@ export const { handlers, auth, signIn, signOut } = NextAuth( () => ( { if ( avatar.find( ( file ) => file.includes( user.id ) ) ) { - session.user.image = `${ process.env.__NEXT_ROUTER_BASEPATH }/avatars/${ avatar }`; + session.user.image = `/avatars/${ avatar }`; } } }