다음.js 다른 페이지로 리디렉션
나는 Next.js에 새로 들어왔고, 예를 들어 시작 페이지( / )에서 hello-nextjs로 어떻게 리디렉션할지 궁금하다.사용자가 페이지를 로드한 후 경로 === /hello-nextjs로 리디렉션되는지 확인
리액터-루터(react-router)에서 우리는 다음과 같은 일을 한다.
<Switch>
<Route path="/hello-nextjs" exact component={HelloNextjs} />
<Redirect to="/hello-nextjs" /> // or <Route path="/" exact render={() => <Redirect to="/hello-nextjs" />} />
</Switch>
12★★이름: Next.js >= 12
이제 미들웨어를 사용하여 리디렉션하고_middleware.js
페이지 폴더 내 파일(또는 페이지 내 하위 폴더)
import { NextResponse, NextRequest } from 'next/server'
export async function middleware(req, ev) {
const { pathname } = req.nextUrl
if (pathname == '/') {
return NextResponse.redirect('/hello-nextjs')
}
return NextResponse.next()
}
업데이트: Next.js >= 10
Next.js 10에서 서버측 리디렉션(클라이언트측 리디렉션은 아래 참조)을redirect
열쇠를 안에 넣다getServerSideProps
또는getStaticProps
:
export async function getServerSideProps(context) {
const res = await fetch(`https://.../data`)
const data = await res.json()
// or use context.resolvedUrl for conditional redirect
// if(context.resolvedUrl == "/")
if (!data) {
return {
redirect: {
destination: '/hello-nextjs',
permanent: false,
},
}
}
return {
props: {}, // will be passed to the page component as props
}
}
참고 : 사용getServerSideProps
앱이 SSR로 강제 이동되며, 빌드 타임에 리디렉션도 지원되지 않음, 빌드 타임에 리디렉션이 알려진 경우 다음.config.js 내부에 리디렉션을 추가하십시오.
인next.js
페이지를 로드한 후 다음을 사용하여 리디렉션할 수 있음Router
ex :
import Router from 'next/router'
componentDidMount(){
const {pathname} = Router
if(pathname == '/' ){
Router.push('/hello-nextjs')
}
}
또는 Hooks와 함께:
import React, { useEffect } from "react";
import Router from 'next/router'
...
useEffect(() => {
const {pathname} = Router
if(pathname == '/' ){
Router.push('/hello-nextjs')
}
});
리디렉션 전에 플래시를 방지하려면 다음과 같은 간단한 트릭을 사용하십시오.
import React, { useEffect,useState } from "react";
import Router from 'next/router'
const myPage = ()=>{
const [loaded,setLoaded] = useState(false)
useEffect(() => {
const {pathname} = Router
// conditional redirect
if(pathname == '/' ){
// with router.push the page may be added to history
// the browser on history back will go back to this page and then forward again to the redirected page
// you can prevent this behaviour using location.replace
Router.push('/hello-nextjs')
//location.replace("/hello-nextjs")
}else{
setLoaded(true)
}
},[]);
if(!loaded){
return <div></div> //show nothing or a loader
}
return (
<p>
You will see this page only if pathname !== "/" , <br/>
</p>
)
}
export default myPage
나는 일반적으로 당신이 사용할 수 있을 때 클라이언트 리디렉션에 대한 좋은/우월한 접근 방식이 아니라고 말하고 싶다.next.config.js
리디렉션하거나 구성 요소의 조건부 렌더링을 더 잘 사용한다.
나는 여기에 있는 모든 예들로 간단한 리포를 만들었다.
주의바트
첫째, 클라이언트 측 리디렉션(반응 내), 서버 측 리디렉션(301 HTTP 응답) 또는 서버 측 리디렉션 + 인증(301 HTTP 응답)이 필요한지 여부를 확인해야 하지만 인증을 확인하는 논리도 가지고 있어야 한다.
이것이 내가 쓸 수 있는 가장 완전한 대답이다.하지만, 대부분의 시나리오에서, 당신은 이것들 중 어떤 것도 필요하지 않다.리액션 앱에서처럼 리디렉션하십시오.먼저 클라이언트 측 재조정을 선호하십시오.그냥 사용useEffect
+router.push
그리고 이것이 마지막입니다.
서버측 리디렉션은 특히 개인 페이지를 "보안"하고 싶을 때는 유혹적이지만, 당신이 정말로 필요한지 여부를 평가해야 한다.보통은 그렇지 않아.인증 토큰과 새로 고침 토큰을 관리하는 것과 같은 예기치 않은 복잡성을 유발한다.대신, 이러한 종류의 검사를 처리하기 위해 게이트웨이 서버, 역방향 프록시 또는 초기 서버를 아키텍처에 추가할 수 있다.
Next.js는 React 앱일 뿐이며 SSR과 같은 Next.js 고급 기능을 사용하는 것은 당신의 맥락에서 정당화되어야 할 비용으로 제공된다는 것을 명심하라.
다음 9.4 대답
안녕, 다음은 모든 시나리오에서 작동하는 구성 요소의 예:
Vulcan next starter with Private 액세스
답은 엄청나다, SO 규칙을 어긴다면 미안하다만, 180줄짜리 코드를 붙여넣고 싶지는 않다.SSR과 정적 내보내기를 모두 지원하려면 Next에서 리디렉션을 처리하기 쉬운 패턴이 없다.
각 시나리오에는 특정 패턴이 필요하다.
- 서버측 렌더링: 허용되는 경우 페이지를 렌더링하고, 허용되지 않는 경우 HTTP 리디렉션
- 정적 렌더링(서버 측): 아무것도 렌더링하지 않지만 빌드에 페이지를 포함
- 클라이언트 측 렌더링, 정적 내보내기 후: 사용자가 인증되었는지 확인하고 리디렉션 여부를 확인하십시오.이 검사 중 또는 리디렉션 중인지에 대해서는 아무것도 표시하지 않는다.
- 다음/이후 클라이언트 리디렉션: 동일한 동작을 사용하여 클라이언트 측 렌더링.
- SSR 이후 클라이언트 측 렌더링: getInitialPropes를 통해 전달된 소품을 사용하여 사용자가 처음에 렌더링할 때 직접 허용되는지 여부를 확인하십시오.좀 더 빠를 뿐이지, 멍한 섬광을 피하면 돼.
작성 시점(다음 9.4)에는 다음 9.4를 사용해야 한다.getInitialProps
아닌getServerSideProps
, 그렇지 않으면 당신은 할 수 있는 능력을 잃는다.next export
.
다음 9.5 업데이트
논평에서 @Arthur에 의해 언급된 바와 같이, 9.5에는 next.config.js에서 리디렉션을 설정할 수 있는 가능성도 포함되어 있다.이 기능의 한계는 아직 명확하지 않지만, 예를 들어, 페이지를 이동하거나 제한된 기간 동안만 액세스를 허용해야 하는 경우와 같이 글로벌 수정 사항인 것 같다.따라서 이들은 요청 컨텍스트에 액세스할 수 없는 것 같기 때문에 예를 들어 인증을 취급하는 것이 아니다.다시 한 번, 확인된다.
다음 10개 새로운 문서 업데이트
이 솔루션은 인증에 따라 리디렉션에 한정된다.
로부터 인증을 받는 것을 좋아하지 않는다.getServerSideProps
왜냐하면 내 생각에 그것은 너무 늦었고 리프레시 토큰을 다루는 것과 같은 고급 패턴을 설정하기가 어려울 수 있기 때문이다.그러나 그것이 공식적인 해결책이다.
또한 인증되지 않은 콘텐츠의 플래시를 방지하는 Vercel의 대시보드가 어떻게 작동하는지(작성 당시)에 따라 이 티켓에 문서화된 접근 방식을 확인하십시오.
다음 10.2 헤더 및 쿠키 기반 업데이트 다시 쓰기
다음 10.2에서는 헤더와 쿠키를 기반으로 다시 쓰기를 소개한다.인증 쿠키 또는 헤더의 존재를 기반으로 서버측을 리디렉션하는 훌륭한 방법.
그러나 이것은 안전한 리디렉션은 아니라는 것을 명심하라.사용자는 잘못된 토큰으로 요청 헤더를 변경할 수 있다.토큰 유효성을 실제로 확인하고 헤더를 올바르게 설정하려면 여전히 게이트웨이, 역방향 프록시 또는 선행 서버가 필요하다.
편집: URL은 변경되지 않는다는 점에 유의하십시오.rewrite는 URL을 응용 프로그램의 기존 페이지로 가리키며 URL을 변경하지 않고 "가상" URL을 가질 수 있다.
사용 사례 예: 페이지가 있다고 가정해 보십시오.src/contact.tsx
리디렉션 번역된 , thoughlygo i18n 리.페이지 이름 자체를 다시 작성하여 번역("연락처")할 수 있다./de/kontact
로/de/contact
.
다음 12개 업데이트
이제 미들웨어는 서버측 리디렉션을 완전히 제어할 수 있게 해준다.
그러나 대부분의 경우 클라이언트 측에서 리디렉션하고 확인하는 것으로 충분하다는 점을 다시 한 번 명심하십시오.
이전 답변(작동하지만 정적인 렌더링이 지저분함)
반공예
그with-cookie-auth
예제가 로 리디렉션되다.getInitialProps
그것이 유효한 패턴인지 아닌지는 아직 확실하지 않지만, 여기에 코드가 있다.
Profile.getInitialProps = async ctx => {
const { token } = nextCookie(ctx)
const apiUrl = getHost(ctx.req) + '/api/profile'
const redirectOnError = () =>
typeof window !== 'undefined'
? Router.push('/login')
: ctx.res.writeHead(302, { Location: '/login' }).end()
try {
const response = await fetch(apiUrl, {
credentials: 'include',
headers: {
Authorization: JSON.stringify({ token }),
},
})
if (response.ok) {
const js = await response.json()
console.log('js', js)
return js
} else {
// https://github.com/developit/unfetch#caveats
return await redirectOnError()
}
} catch (error) {
// Implementation or Network error
return redirectOnError()
}
}
서버측과 클라이언트측을 모두 처리한다.그fetch
을 실제로 당신은 의 함수로 하는 것을 call은 auth를 을다. 당신은 이것을 다른 함수로 캡슐화하는 것을 원할 수 있다.
내가 대신 충고하고 싶은 것은
1. 서버 측 렌더에서 리디렉션(SSR 중에 플래시를 사용하지 않음)
이것이 가장 흔한 경우다.처음 로드할 때 초기 페이지가 깜박이지 않도록 이 시점에서 리디렉션하려는 경우.
MyApp.getInitialProps = async appContext => {
const currentUser = await getCurrentUser(); // define this beforehand
const appProps = await App.getInitialProps(appContext);
// check that we are in SSR mode (NOT static and NOT client-side)
if (typeof window === "undefined" && appContext.ctx.res.writeHead) {
if (!currentUser && !isPublicRoute(appContext.router.pathname)) {
appContext.ctx.res.writeHead(302, { Location: "/account/login" });
appContext.ctx.res.end();
}
}
return { ...appProps, currentUser };
};
2. componentDidMount에서 리디렉션(예: 정적 모드에서 SSR이 비활성화된 경우 유용함)
이것은 클라이언트 측 렌더링에 대한 대비책이다.
componentDidMount() {
const { currentUser, router } = this.props;
if (!currentUser && !isPublicRoute(router.pathname)) {
Router.push("/account/login");
}
}
정적 빌드 중에는 리디렉션할 수 없기 때문에 정적 모드에서 초기 페이지를 깜박이는 것을 피할 수 없었지만 일반적인 접근 방식보다 나은 것 같다.내가 진행하면서 편집해 볼게.
세 가지 접근법이 있다.
1.이벤트 또는 기능에 대한 리디렉션:
import Router from 'next/router';
<button type="button" onClick={() => Router.push('/myroute')} />
2.고리를 사용한 리디렉션:
import Router , {useRouter} from 'next/router';
const router = useRouter()
<button type="button" onClick={() => router.push('/myroute')} />
3.링크 리디렉션:
Nextjs rothero.<a>
새 탭에서 여는 것과 같은 것을 위해 링크 안에 태그가 있어야 한다!
import Link from 'next/link';
<Link href="/myroute">
<a>myroute</a>
</Link>
서버측 라우팅에 대해 다음과 같은 몇 가지 다른 옵션이 있다.asPath
수 있다 설명된 모든 접근 방식에서 asPath를 추가하여 클라이언트와 서버 측 모두를 리디렉션할 수 있다.
다음.js 10+는 우리에게 리디렉션을 만들기 위한 추가적이고 우아한 솔루션을 제공하고 있다.
SERVER-SIDE - 다음을 사용하십시오.
getServerSideProps
아래 예제는 확인할 수 있는 추가 세션이 있다고 가정한다(하지만 원하는 모든 세션이 될 수 있음).세션이 비어 있고 서버 측에 있는 경우(
context.res
), 즉 사용자가 로그인하지 않았으므로 로그인 페이지로 리디렉션해야 함(/login
또 할 수 . 또 다른 방법으로 우리는 통과할 수 있다.session
로props
그리고 로 리디렉션한다./dashboard
:import { getSession } from 'next-auth/client'; export const getServerSideProps = async (context) => { const session = await getSession(context); if(context.res && !session) { return { redirect: { permanent: false, destination: '/login' } } } return { props: { session }, redirect: { permanent: false, destination: '/dashboard' } } }
클라이언트 측 - 예를 들어 사용할 수 있음
useRouter
스위치:import { useRouter } from 'next/router'; import { useSession } from 'next-auth/client'; const router = useRouter(); const [ session, loading ] = useSession(); if (typeof window !== 'undefined' && loading) return null; if (typeof window !== 'undefined' && !session) { router.push('/login'); } router.push('/dashboard');
자세한 내용은 https://github.com/vercel/next.js/discussions/14890를 참조하십시오.
유효 기간:NextJS 9.5.0+
- 만들다
next.config.js
파일 - 소스 및 대상 URL 추가(외부 도메인의 경우 영구 리디렉션으로 설정할 수 있음)
module.exports = {
async redirects() {
return [
{
source: '/team',
destination: '/about',
permanent: false,
},
{
source: "/blog",
destination:
"https://blog.dundermifflin.com",
permanent: true,
},
];
},
};
https://github.com/vercel/next.js/tree/canary/examples/redirects
다음은 두 가지 복사 붙여넣기 수준의 예: 브라우저용과 서버용 예제.
https://dev.to/justincy/client-side-and-server-side-redirection-in-next-js-3ile
루트(/)에서 홈(/home)이라는 페이지로 리디렉션하고 싶다고 가정합시다. (/홈)
기본 인덱스 파일에서 다음을 붙여넣으십시오.
클라이언트 측
import { useRouter } from 'next/router'
function RedirectPage() {
const router = useRouter()
// Make sure we're in the browser
if (typeof window !== 'undefined') {
router.push('/home')
}
}
export default RedirectPage
서버측
import { useRouter } from 'next/router'
function RedirectPage({ ctx }) {
const router = useRouter()
// Make sure we're in the browser
if (typeof window !== 'undefined') {
router.push('/home');
return;
}
}
RedirectPage.getInitialProps = ctx => {
// We check for ctx.res to make sure we're on the server.
if (ctx.res) {
ctx.res.writeHead(302, { Location: '/home' });
ctx.res.end();
}
return { };
}
export default RedirectPage
@Nico의 대답은 당신이 수업을 사용할 때 문제를 해결한다.
만약 당신이 기능을 사용하고 있다면 당신은 사용할 수 없다.componentDidMount
대신 반응 후크를 사용할 수 있다.useEffect
.
import React, {useEffect} from 'react';
export default function App() {
const classes = useStyles();
useEffect(() => {
const {pathname} = Router
if(pathname == '/' ){
Router.push('/templates/mainpage1')
}
}
, []);
return (
null
)
}
2019년에 리액션은 후크를 도입했다.수업보다 훨씬 빠르고 효율적이야
NextJs v9.5 이상에서는 다음.config.js 파일에서 리디렉션 및 다시 쓰기를 구성할 수 있다.
하지만 만약 당신이 사용하고 있다면trailingSlash: true
올바른 일치를 위해 원본 경로가 슬래시로 끝나는지 확인하십시오.
module.exports = {
trailingSlash: true,
async redirects() {
return [
{
source: '/old/:slug/', // Notice the slash at the end
destination: '/new/:slug',
permanent: false,
},
]
},
}
또한 라우팅에 영향을 미칠 수 있는 다른 플러그인 및 구성(예: 다음 이미지)도 고려해야 한다.
설명서: https://nextjs.org/docs/api-reference/next.config.js/redirects
redirect-to.ts
import Router from "next/router";
export default function redirectTo(
destination: any,
{ res, status }: any = {}
): void {
if (res) {
res.writeHead(status || 302, { Location: destination });
res.end();
} else if (destination[0] === "/" && destination[1] !== "/") {
Router.push(destination);
} else {
window.location = destination;
}
}
_app.tsx
import App, {AppContext} from 'next/app'
import Router from "next/router"
import React from 'react'
import redirectTo from "../utils/redirect-to"
export default class MyApp extends App {
public static async getInitialProps({Component, ctx}: AppContext): Promise<{pageProps: {}}> {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
if (ctx.pathname === "" || ctx.pathname === "/_error") {
redirectTo("/hello-next-js", { res: ctx.res, status: 301 }); <== Redirect-To
return {pageProps};
}
return {pageProps};
}
render() {
const {Component, pageProps} = this.props;
return <Component {...pageProps}/>
}
}
는 이 의 이 기지에 했다.Next.JS
루트 페이지를 정의하여 리디렉션 서버측과 클라이언트측을 처리한다.루트 페이지의 코드:
import { useEffect } from "react";
import Router from "next/router";
const redirectTo = "/hello-nextjs";
const RootPage = () => {
useEffect(() => Router.push(redirectTo));
return null;
};
RootPage.getInitialProps = (ctx) => {
if (ctx.req) {
ctx.res.writeHead(302, { Location: redirectTo });
ctx.res.end();
}
};
export default RootPage;
SPA처럼 프로그램이 실행되고 사용자가 주소 표시줄에 붙여넣은 수신 무효(또는 유효한) 경로 이름을 가로채려는 의도를 가진 경우, 다음 방법을 참조하십시오.
만약 당신의 길이,
enum ERoutes {
HOME = '/',
ABOUT = '/about',
CONTACT = '/contact'
}
사용자 정의 추가_error
아직 없는 경우 페이지를 페이지하고 추가하십시오.
import React from 'react';
import { NextPage } from 'next';
import { useDispatch } from 'react-redux';
import { useRouter } from 'next/router';
const Error: NextPage = () => {
const { asPath, push } = useRouter();
const dispatch = useDispatch();
React.useEffect(() => {
const routeValid = Object.values(ERoutes).includes(asPath);
if (routeValid) {
// do some stuff, such as assigning redux state to then render SPA content in your index page
} else {
// you can either continue to render this _error component, or redirect to your index page,
// where you may have your own error component that is displayed based on your app state.
// In my case, I always redirect to '/' (as you can see below, where I push('/'), but before doing so,
// I dispatch relevant redux actions based on the situation
}
// I redirect to root always, but you can redirect only if routeValid === true
push('/');
}, []);
return (
<div>Error because '{asPath}' does not exist</div>
);
};
export default Error;
참조URL: https://stackoverflow.com/questions/58173809/next-js-redirect-from-to-another-page
'Programing' 카테고리의 다른 글
Redex의 대기열 동작 (0) | 2022.03.22 |
---|---|
Vuetify의 기본 너비 변경JS DataTable 셀 (0) | 2022.03.22 |
Vue 라우터에서 대상 구성 요소를 동적으로 설정하는 방법 (0) | 2022.03.22 |
Python의 dritt.keys()는 왜 집합이 아닌 목록을 반환하는가? (0) | 2022.03.22 |
반응 환경에서 알 수 없는 모듈 "crypto" 필요 (0) | 2022.03.22 |