Другое

Исправление React Router на GitHub Pages: Полное руководство

Решение проблем с React Router при развертывании на GitHub Pages. Узнайте, как настроить basename, создать перенаправления 404 и использовать HashRouter для правильной маршрутизации на стороне клиента.

Почему моя конфигурация React Router работает на localhost, но не на GitHub Pages?

Я настроил React-приложение с использованием React Router, и оно работает идеально при запуске на локальном сервере разработки. Однако после развертывания на GitHub Pages маршрутизация работает некорректно. Вот моя текущая конфигурация роутера:

jsx
import { BrowserRouter, Routes, Route } from "react-router-dom";
import './App.css';
import 'bootstrap-icons/font/bootstrap-icons.css';
import NavbarEffect from './Components/navbar';
import Home from './Page/home';
import Services from "./Page/services";
import Project from "./Page/project";
import Contact from "./Page/contact";
import Notfound from "./Page/notfound";
import About from "./Page/about";

function App() {
  const navLinks = [
    { name: "Home", href: "/" },
    { name: "About", href: "/about" },
    { name: "Services", href: "/services" },
    { name: "Projects", href: "/project" },
    { name: "Contact", href: "/contact" },
  ];

  return (
    <BrowserRouter>
      <NavbarEffect links={navLinks} />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About/>}/>
        <Route path="/project" element={<Project />} />
        <Route path="/services" element={<Services />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="*" element={<Notfound />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Что может быть причиной этой проблемы, и как я могу исправить свою конфигурацию React Router, чтобы она корректно работала на GitHub Pages?

Проблема возникает из-за того, что React Router использует клиентскую маршрутизацию, в то время как GitHub Pages рассматривает ваше приложение как статический файловый сервер. При переходе на маршрут, такой как /about на GitHub Pages, сервер ищет фактический файл /about, а не обслуживает ваш index.html и не позволяет React Router обрабатывать маршрутизацию.

Чтобы исправить это, необходимо правильно настроить как React Router, так и GitHub Pages для совместной работы. Вот ключевые решения:

Содержание

Понимание основной причины

Когда вы запускаете свое React-приложение локально, сервер разработки настроен на обработку любого URL путем постоянного обслуживания index.html и предоставления React Router возможности обрабатывать маршрутизацию. Однако GitHub Pages - это сервис статического хостинга, который обслуживает файлы на основе их фактических путей в репозитории.

Когда пользователь посещает https://yourusername.github.io/yourrepo/about на GitHub Pages, сервер ищет файл по пути /about в вашем репозитории. Поскольку у вас нет физических файлов для каждого маршрута, он возвращает страницу ошибки 404 вместо файла index.html вашего React-приложения.

Решение 1: Использование basename в BrowserRouter

Первым шагом является настройка вашего BrowserRouter для работы со структурой URL GitHub Pages.

jsx
import { BrowserRouter, Routes, Route } from "react-router-dom";

function App() {
  const navLinks = [
    { name: "Главная", href: "/" },
    { name: "О нас", href: "/about" },
    { name: "Услуги", href: "/services" },
    { name: "Проекты", href: "/project" },
    { name: "Контакты", href: "/contact" },
  ];

  return (
    <BrowserRouter basename="/your-repo-name">
      <NavbarEffect links={navLinks} />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/project" element={<Project />} />
        <Route path="/services" element={<Services />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="*" element={<Notfound />} />
      </Routes>
    </BrowserRouter>
  );
}

Свойство basename сообщает React Router, что все маршруты должны иметь префикс с именем вашего репозитория, что соответствует структуре URL GitHub Pages.

Решение 2: Создание файла перенаправления 404

Создайте файл 404.html в папке public вашего React-проекта со следующим содержанием:

html
<!DOCTYPE html>
<html>
  <head>
    <title>Страница не найдена</title>
    <script>
      // Перенаправление на главную страницу
      window.location.href = "/your-repo-name/";
    </script>
  </head>
  <body>
    <h1>Страница не найдена</h1>
    <p>Страница, которую вы ищете, не существует.</p>
  </body>
</html>

Этот файл перенаправляет все запросы 404 обратно в ваше основное приложение, позволяя React Router обрабатывать маршрутизацию.

Решение 3: Альтернатива с HashRouter

Если приведенные выше решения не работают, вы можете переключиться с BrowserRouter на HashRouter, который использует хеш URL для маршрутизации и лучше работает со статическим хостингом:

jsx
import { HashRouter, Routes, Route } from "react-router-dom";

function App() {
  return (
    <HashRouter>
      <NavbarEffect links={navLinks} />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/project" element={<Project />} />
        <Route path="/services" element={<Services />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="*" element={<Notfound />} />
      </Routes>
    </HashRouter>
  );
}

HashRouter создает URL вида https://yourusername.github.io/yourrepo/#/about, которые обрабатываются полностью на стороне клиента, избегая проблем с серверной маршрутизацией.

Решение 4: Конфигурация развертывания на GitHub Pages

Убедитесь, что ваше развертывание на GitHub Pages правильно настроено. Создайте или обновите ваш package.json с правильным скриптом развертывания:

json
{
  "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
  }
}

Установите пакет gh-pages:

bash
npm install gh-pages --save-dev

Эта настройка гарантирует, что ваш сборка будет развернута в ветку gh-pages, которую GitHub Pages использует для обслуживания вашего сайта.

Полная реализация решения

Вот полное решение, объединяющее несколько подходов:

  1. Обновите ваш App.js:
jsx
import { BrowserRouter, Routes, Route } from "react-router-dom";
import './App.css';
import 'bootstrap-icons/font/bootstrap-icons.css';
import NavbarEffect from './Components/navbar';
import Home from './Page/home';
import Services from "./Page/services";
import Project from "./Page/project";
import Contact from "./Page/contact";
import Notfound from "./Page/notfound";
import About from "./Page/about";

function App() {
  const navLinks = [
    { name: "Главная", href: "/" },
    { name: "О нас", href: "/about" },
    { name: "Услуги", href: "/services" },
    { name: "Проекты", href: "/project" },
    { name: "Контакты", href: "/contact" },
  ];

  return (
    <BrowserRouter basename="/your-repo-name">
      <NavbarEffect links={navLinks} />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/project" element={<Project />} />
        <Route path="/services" element={<Services />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="*" element={<Notfound />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;
  1. Создайте файл 404.html в вашей папке public:
html
<!DOCTYPE html>
<html>
  <head>
    <title>Страница не найдена</title>
    <script>
      // Перенаправление на главную страницу
      window.location.href = "/your-repo-name/";
    </script>
  </head>
  <body>
    <h1>Страница не найдена</h1>
    <p>Страница, которую вы ищете, не существует.</p>
  </body>
</html>
  1. Обновите ваш package.json:
json
{
  "name": "your-app-name",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.8.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
  },
  "devDependencies": {
    "gh-pages": "^4.0.0",
    "react-scripts": "5.0.1"
  },
  "homepage": "https://yourusername.github.io/your-repo-name"
}

Тестирование развертывания

После реализации этих решений:

  1. Запустите npm run build для создания производственной сборки
  2. Запустите npm run deploy для развертывания на GitHub Pages
  3. Протестируйте все ваши маршруты: /, /about, /services, /project, /contact
  4. Протестируйте обновление каждой страницы, чтобы убедиться, что она загружается правильно
  5. Протестируйте прямой переход по URL, чтобы убедиться, что они работают

Если вы по-прежнему сталкиваетесь с проблемами, вы также можете попробовать использовать пользовательский файл public/index.html для обеспечения правильной маршрутизации:

html
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="Описание вашего приложения" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <title>Ваше приложение</title>
  </head>
  <body>
    <noscript>Вам необходимо включить JavaScript для запуска этого приложения.</noscript>
    <div id="root"></div>
  </body>
</html>

Этот комплексный подход должен решить проблемы маршрутизации при развертывании вашего React Router приложения на GitHub Pages.

Источники

  1. Документация React Router - BrowserRouter
  2. Документация GitHub Pages - О GitHub Pages
  3. Документация Create React App - Развертывание

Заключение

Проблемы с маршрутизацией, которые вы испытываете с React Router на GitHub Pages, являются распространенными, но решаемыми. Ключевые решения включают:

  1. Настройку basename в BrowserRouter для соответствия структуре URL вашего репозитория GitHub Pages
  2. Создание файла перенаправления 404.html для обработки ошибок серверной маршрутизации
  3. Использование HashRouter в качестве альтернативы, если BrowserRouter продолжает вызывать проблемы
  4. Правильную конфигурацию развертывания в package.json для обеспечения правильных процессов сборки и развертывания

Реализовав эти решения, ваше React Router приложение будет работать бесшовно как на localhost, так и на GitHub Pages. Не забудьте заменить "your-repo-name" на фактическое имя вашего репозитория во всех конфигурациях. Комбинация клиентской маршрутизации с правильными механизмами отката на стороне сервера обеспечивает плавный пользовательский опыт независимо от того, как пользователи перемещаются по вашему приложению.

Авторы
Проверено модерацией
Модерация