← Назад к вопросам

Как сделать редирект пользователя на другую страницу?

2.0 Middle🔥 141 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как сделать редирект пользователя на другую страницу?

В React / Next.js: useRouter хук

// === Next.js App Router (рекомендуется) ===

'use client'; // клиентский компонент

import { useRouter } from 'next/navigation';
import { useEffect } from 'react';

export function RedirectComponent() {
  const router = useRouter();

  // Редирект после действия пользователя
  function handleLogin() {
    // ... обработка логина
    router.push('/dashboard'); // переход на /dashboard
  }

  // Редирект при загрузке компонента
  useEffect(() => {
    if (!isAuthenticated) {
      router.push('/login');
    }
  }, [isAuthenticated, router]);

  return (
    <button onClick={handleLogin}>
      Log In
    </button>
  );
}

// === Next.js Pages Router (старый стиль) ===

import { useRouter } from 'next/router';

export function OldStyleRedirect() {
  const router = useRouter();

  function handleClick() {
    router.push('/other-page');
  }

  return <button onClick={handleClick}>Go</button>;
}

// === Методы router ===

router.push('/path');           // переход обычный
router.replace('/path');        // замена в истории (back не будет работать)
router.prefetch('/path');       // предзагрузка страницы для быстрого перехода
router.back();                  // назад в истории
router.forward();               // вперёд в истории

Простой React SPA (React Router)

// === Использование useNavigate из react-router-dom ===

import { useNavigate } from 'react-router-dom';

export function MyComponent() {
  const navigate = useNavigate();

  function handleClick() {
    navigate('/about');
  }

  function goBack() {
    navigate(-1); // вернуться на предыдущую страницу
  }

  function replaceHistory() {
    navigate('/home', { replace: true }); // замена вместо добавления в историю
  }

  return (
    <>
      <button onClick={handleClick}>Go to About</button>
      <button onClick={goBack}>Back</button>
      <button onClick={replaceHistory}>Replace</button>
    </>
  );
}

// === Редирект при загрузке компонента ===

export function ProtectedPage() {
  const navigate = useNavigate();
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    checkAuth().then((isAuth) => {
      if (!isAuth) {
        navigate('/login', { replace: true });
      }
      setIsLoading(false);
    });
  }, [navigate]);

  if (isLoading) return <div>Loading...</div>;

  return <div>Protected Content</div>;
}

// === Компонент <Navigate> для встроенных редиректов ===

import { Navigate } from 'react-router-dom';

export function PrivateRoute({ isAuthenticated, children }) {
  if (!isAuthenticated) {
    return <Navigate to="/login" replace />;
  }
  return children;
}

// Использование:
<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route
      path="/dashboard"
      element={
        <PrivateRoute isAuthenticated={isAuth}>
          <Dashboard />
        </PrivateRoute>
      }
    />
  </Routes>
</BrowserRouter>

Vanilла JavaScript

// === Простой редирект через location ===

// Способ 1: window.location.href (полная перезагрузка страницы)
window.location.href = '/new-page';

// Способ 2: window.location.replace (замена в истории)
window.location.replace('/new-page');

// Способ 3: window.location.pathname (только путь)
window.location.pathname = '/new-page';

// === С задержкой ===

setTimeout(() => {
  window.location.href = '/thank-you';
}, 2000); // редирект через 2 секунды

// === Редирект на внешний URL ===

window.location.href = 'https://example.com';

// === История браузера (History API) ===

history.pushState(
  { page: 1 }, // state object
  'Title',      // title
  '/new-url'    // новый URL
);

history.replaceState(null, '', '/replace-url');

history.back();    // эквивалент нажатия back button
history.forward(); // эквивалент нажатия forward button
history.go(-2);    // вернуться на 2 страницы назад

Условные редиректы и защита маршрутов

// === Next.js: защита маршрутов через middleware ===

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const token = request.cookies.get('auth_token');

  // Если пользователь не авторизован и хочет на /dashboard
  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  // Если авторизован и пытается на /login
  if (token && request.nextUrl.pathname === '/login') {
    return NextResponse.redirect(new URL('/dashboard', request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ['/dashboard/:path*', '/login'],
};

// === React Router: Route Guards ===

function ProtectedRoute({ isAuth, children }) {
  return isAuth ? children : <Navigate to="/login" />;
}

function Routes() {
  const [isAuth, setIsAuth] = useState(false);

  return (
    <BrowserRouter>
      <Routes>
        <Route path="/login" element={<LoginPage />} />
        <Route
          path="/dashboard"
          element={
            <ProtectedRoute isAuth={isAuth}>
              <DashboardPage />
            </ProtectedRoute>
          }
        />
      </Routes>
    </BrowserRouter>
  );
}

// === Программный редирект после проверки ===

export function LoginForm() {
  const navigate = useNavigate();
  const [error, setError] = useState('');

  async function handleSubmit(e) {
    e.preventDefault();

    try {
      const response = await fetch('/api/login', {
        method: 'POST',
        body: JSON.stringify({ email, password }),
      });

      if (response.ok) {
        // Успех — редирект на dashboard
        navigate('/dashboard');
      } else {
        // Ошибка — показываем сообщение
        setError('Invalid credentials');
      }
    } catch (err) {
      setError('Network error');
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input type="email" />
      <input type="password" />
      {error && <p className="text-red-500">{error}</p>}
      <button>Sign In</button>
    </form>
  );
}

Параметры и query strings при редиректе

// === Передача параметров ===

// Next.js
router.push('/search?q=javascript&page=2');

// React Router
navigate('/search?q=javascript&page=2');

// Vanilла JS
window.location.href = '/search?q=javascript&page=2';

// === Чтение параметров ===

// Next.js
import { useSearchParams } from 'next/navigation';

export function SearchPage() {
  const searchParams = useSearchParams();
  const q = searchParams.get('q');
  const page = searchParams.get('page');

  return <div>Searching for: {q}, page: {page}</div>;
}

// React Router
import { useSearchParams } from 'react-router-dom';

export function SearchPage() {
  const [searchParams] = useSearchParams();
  const q = searchParams.get('q');

  return <div>Results for: {q}</div>;
}

// Vanilла JS
const params = new URLSearchParams(window.location.search);
const q = params.get('q');

Редирект со статус-кодами (SSR)

// === Next.js: редирект на сервере ===

export async function getServerSideProps() {
  // Проверяем данные на сервере
  const data = await fetchData();

  if (!data.isValid) {
    return {
      redirect: {
        destination: '/error',
        permanent: false, // 307 вместо 308
      },
    };
  }

  return {
    props: { data },
  };
}

// === Next.js: постоянный редирект в next.config.js ===

const nextConfig = {
  redirects: async () => [
    {
      source: '/old-page',
      destination: '/new-page',
      permanent: true, // 301 редирект
    },
    {
      source: '/docs/:path*',
      destination: '/help/:path*',
      permanent: false, // 307 редирект
    },
  ],
};

// === Next.js: редирект для всех неизвестных маршрутов ===

redirects: async () => [
  {
    source: '/:path*',
    destination: '/404',
    permanent: false,
  },
];

Best Practices

// OK: использовать правильные инструменты для редиректов

// Next.js -> useRouter хук
const router = useRouter();
router.push('/page');

// React Router -> useNavigate хук
const navigate = useNavigate();
navigate('/page');

// NOT OK: window.location для SPA (полная перезагрузка)
window.location.href = '/page'; // слишком медленно!

// OK: использовать replace для определённых сценариев
router.push('/dashboard', { replace: true }); // логин -> dashboard (без back)

// OK: проверять авторизацию перед редиректом
if (!token) {
  navigate('/login');
}

// NOT OK: редиректить без проверки в useEffect (бесконечный цикл)
useEffect(() => {
  navigate('/page'); // будет срабатывать каждый раз!
}, []); // не забывай зависимости!

// OK: редирект с проверкой условия
useEffect(() => {
  if (!user) {
    navigate('/login');
  }
}, [user, navigate]);
Как сделать редирект пользователя на другую страницу? | PrepBro