NextJS/Django Ручной ввод URL-адресов

Я пытаюсь создать приложение, которое использует Django на бэкенде и NextJS на фронтэнде.

Я установил это, статически экспортируя приложение NextJS, затем приложение Django обрабатывает маршрутизацию и использует index.html как ловушку для всех маршрутов, которые оно не знает.

Это работает относительно хорошо, однако я столкнулся с проблемой маршрутизации в NextJS, и я не уверен, откуда именно это происходит. Хотя моя маршрутизация на стороне клиента работает нормально (т.е. компоненты Link работают, как ожидалось), она ничего не делает, если я делаю это, вводя URL.

Моя структура каталогов выглядит следующим образом:

...
- pages
     - _app.tsx
     - index.tsx
     - login.tsx
...

Следовательно, я должен ожидать, что /login будет перенаправлять на страницу входа, и снова это работает, как ожидалось, в теге Link, однако когда я вручную ввожу localhost:8000/login/, он просто перенаправляет на index.tsx.

Некоторые другие потенциально значимые файлы:

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "baseUrl": ".",
    "paths": {
      "@/styles/*": ["styles/*"],
      "@/components/*": ["components/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

next.config.js

/** @type {import('next').NextConfig} */

module.exports = {
    reactStrictMode: true,
    images: {
        loader: "akamai",
        path: "/",
    },
}

У меня есть ощущение, что это происходит потому, что файлы рендерятся на стороне клиента, а не на стороне сервера, но я не видел ничего, что указывало бы на то, что это неизбежный побочный эффект. Для этого я пробовал использовать getStaticPaths и getStaticProps, но ни то, ни другое не работает, как ожидалось. Я даже пробовал использовать свойство redirects, но ничего.

Я действительно в тупике, почему это не работает, и я не могу найти никакой информации об этом - опять же, это наводит меня на мысль, что это просто то, как NextJS работает для CSR, но я действительно не могу поверить, что это так.

Заранее спасибо!

Так что я еще не до конца разобрался с этим, но после более тщательного исследования проблема, похоже, на стороне NextJS, а не Django.

"Реальное" решение - начать использовать NextJS через команду next start, а не статический экспорт. Опять же, основываясь на документации, мне кажется, что это не тот случай, но после перехода на него и получения его для работы с Django все работает как ожидалось.

Однако это не всегда возможно сделать, поэтому, если вы должны использовать статический экспорт, я добавил следующее к моему pages/_app.tsx, чтобы получить функциональные URL:


const router = useRouter()
useEffect(() => {
    try {
        // get pathname and location
        let pathname = router.pathname
        let location = window.location.pathname

        // ensure paths have trailing '/'
        const lastLocation = location.charAt(location.length - 1);
        if (lastLocation != '/') {
            location = `${location}/`
        }
        const lastPath = pathname.charAt(pathname.length - 1);
        if (lastPath != '/') {
            pathname = `${pathname}/`
        }

        // redirect to page in actual url
        if (pathname != location) {
            router.replace(location).then((success) => {
                if (!success) {
                    const newPath = '/404'
                    window.location.pathname = newPath
                    let res = router.replace(newPath)
                }
            })
        }
    } catch (e) {
        console.error(e)
    }
})

Вам также необходимо trailingSlash: true, вписать next.config.js.

Не могу сказать, что я поклонник этого "хака", но, похоже, он работает так, как ожидалось, но я не могу представить, что это "самый правильный" ответ. Однако это полностью исправляет ручной ввод URL, а также любую другую маршрутизацию CSR, т.е. a tags.

Вернуться на верх