Help us understand the problem. What is going on with this article?

nuxtでナビゲーションガード時、リダイレクトしてもlayoutが変わらない問題

More than 1 year has passed since last update.

TL;DR

contextnuxtStatelayout プロパティがあるので、そこにlayout値をぶっこむ!

前提

nuxt.jsでユーザー認証ガードをしなくちゃいけないけれども、LocalStorageに情報保持しなくちゃいけないときとかに、
非SSR な plugin をつくって ナビゲーションガード 設定することあると思います。
さらには非同期な処理も叩かなくてはいけないから、async/await にしちゃう!

そこで以下のように実装しました

~plugin/nav-guard.js(実際のコードではありません)
export default ({app,redirect}) => {
    app.router.beforeEach(async (to,from,next)=>{
      if( /* 非認証ページ */ ) { 
        next();
      } else if( /* 別途ストアの中に認証用データがないとき */ ){
        redirect('/login');
      } else {
        const auth = await なんらかの非同期メソッド();
        if( /* なんらかの非同期メソッドがオッケーだった時 */ ){
          next();
        } else {
          redirect('/login');
        }
      }
    })
}

リダイレクト後のページのlayoutが遷移前のPageComponentのlayoutのママだったんですね。
Vue-devtoolで見てもlayoutそのまま。

これも、universalモードで、直接アクセスしたときにのみ発生してまして、その後CSRで遷移するときは問題ないのです。

対処法

  • redirect ではなく、routerの next でリダイレクトさせても発生
  • redirect ではなく、location.replace を使うと問題なし
  • redirect の時期を setTimeout すると時間によっては問題なし

2つ目は、layout/error を表示させてからリダイレクトする処理をしてた時に発見したんですが、早すぎてもだめでした。
ここも時間上の制約で深く探ってないです。
で、やっぱりredirectで処理させたかったので、\$nextTick ならどうだと思って、
API: コンテキスト - Nuxt.js
でどこからアクセスしようか探してた時に、nuxtState を発見しました。

こんな感じにすると無事正しいlayoutで表示されるようになりました。

~plugin/nav-guard.js(実際のコードではありません)
export default ({app,redirect,nuxtState}) => {
    app.router.beforeEach(async (to,from,next)=>{
      if( /* 非認証ページ */ ) { 
        next();
      } else if( /* 別途ストアの中に認証用データがないとき */ ){
        nuxtState.layout = 'login';
        redirect('/login');
      } else {
        const auth = await なんらかの非同期メソッド();
        if( /* なんらかの非同期メソッドがオッケーだった時 */ ){
          next();
        } else {
          nuxtState.layout = 'login';
          redirect('/login');
        }
      }
    })
}

(ただ、いまだに\$nextTickの実行方法がわかりません。app.\$nextTickは無いと怒られる...)

発生条件(がわかればいいなぁ)

これ、発生条件が自分には把握できず NuxtのGithubにもissue立ててないんですが、

  • nuxt バージョンは 1.4.2
  • universalモード
  • ナビゲーションガードはクライアントサイドのみ
  • コンポーネントが増えてくる前は大丈夫だった(ような気がする)
  • location.replace だと大丈夫

ぐらいしかわかってません。


ぶっちゃけ、全部middleware内で、SSRでもアクセス可能な形の認証にしたかった。
あと、next でやってないのOKなのかなって疑問。
時間ができたら再度nuxt側含めて探ってみる予定です。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away