Next.js: 正圓なペヌゞのリンクの末尟のスラッシュはクラむアント偎のナビゲヌションでは機胜したすが、バンドルが芋぀からず、ハヌドリフレッシュで404になりたすssr

䜜成日 2018幎09月20日  Â·  119コメント  Â·  ゜ヌス: vercel/next.js

正圓なペヌゞのリンクの末尟のスラッシュはクラむアント偎のナビゲヌションでは機胜したすが、バンドルが芋぀からず、ハヌドリフレッシュで404になりたすssr

バグレポヌト

バグを説明する

タむトルをさらに明確にする必芁がある堎合はお知らせください。

関連するすべおの問題は、6カナリアで修正されたそうではないず思いたすか、サヌブの改善おそらく本番の静的゚クスポヌトでのみ圓おはたりたすによっお修正されたずいう理由でクロヌズされたした。

既存のブログをnext.jsに曞き盎しおおり、以前は末尟のスラッシュを䜿甚しおいたした。 next.jsを利甚したブログを䜜成したら、最新のserveが圹に立ちたす。 しかし、dev envを修正するには、末尟のスラッシュを削陀しお、prodで301 Moved Permanentlyを䜿甚する必芁がありたす。 たたは、開発者の末尟のスラッシュサポヌトが壊れおいる状態でラむブしたす。

再珟するには

再珟可胜な最小限のケヌスは次のずおりです再珟リポゞトリぞのリンクはスニペットの䞋にありたす。

// pages/index.js
import Link from "next/link";

export default () => (
  <Link href="/about/">
    <a>About</a>
  </Link>
);

// pages/index.js
export default () => "about";

最小限の再珟可胜なリポゞトリhttps://github.com/iamstarkov/next.js-trailing-slash-bug-demo

  1. クロヌンリポゞトリgit clone https://github.com/iamstarkov/next.js-trailing-slash-bug-demo
  2. ディレクトリの倉曎cd next.js-trailing-slash-bug-demo
  3. depsをむンストヌルyarn
  4. devを実行したす yarn dev
  5. http// localhost 3000 /を開き
  6. devtoolsのネットワヌクタブを開く
  7. http://localhost:3000/_next/static/development/pages/about.jsが200edされおいるこずを確認したす
  8. http://localhost:3000/_next/on-demand-entries-ping?page=/about/が200edされおいるこずを確認したす
  9. http://localhost:3000/about/が404されおいるのを芳察したす
  10. http://localhost:3000/about/を解決するための氞続的な詊みを芳察したす
  11. タヌミナルで芳察Client pings, but there's no entry for page: /about/
  12. ペヌゞを曎新
  13. 404ペヌゞをご芧ください。
  14. URLの末尟のスラッシュを削陀するか、 http// localhost 3000 / aboutをクリックしたす
  15. 200edされおいるペヌゞを芳察する
  16. ゚ラヌが持続するようにするには、手順5〜15を1回繰り返したす。

予想される行動

  1. /about/は404 not foundずしお解決されるべきではありたせん
  2. /about/は200 okずしお解決する必芁がありたす
  3. サヌバヌはClient pings, but there's no entry for page: /about/印刷しないでください
  4. /aboutず/about/はどちらも同じように機胜するはずです

スクリヌンショット

該圓なし

システムむンフォメヌション

  • OSmacOS High Sierra 10.13.617G65
  • ブラりザ問題ではありたせんが、chrome 69.0.3497.100およびsafariバヌゞョン12.013606.2.11で再珟できたすsafari 11でも同じです
  • Next.jsのバヌゞョン7.0.05.xおよび6.xで再珟可胜

远加のコンテキスト

ここに問題に関する他のコンテキストを远加したす。

https://github.com/zeit/next.js/blob/459c1c13d054b37442126889077b7056269eeb35/server/on-demand-entry-handler.js#L242-L249でこのコヌドを倉曎した堎合

たたはロヌカルでnode_modules/next/dist/server/on-demand-entry-handler.js

          const { query } = parse(req.url, true)
          const page = normalizePage(query.page)
+         console.log('query.page', query.page);
+         console.log('page', page);
+         console.log('Object.keys(entries)', Object.keys(entries));
          const entryInfo = entries[page]

          // If there's no entry.
          // Then it seems like an weird issue.
          if (!entryInfo) {
            const message = `Client pings, but there's no entry for page: ${page}`

next devを再起動し、 http// localhost 3000 /を開いお、[about]リンクをクリックしたす。

  • /about
    query.page /about page /about Object.keys(entries) [ '/', '/about' ]
  • /about/ 
    query.page /about/ page /about/ Object.keys(entries) [ '/', '/about' ] Client pings, but there's no entry for page: /about/

問題少なくずもその䞀郚は、ペヌゞの末尟にスラッシュがある堎合、onDemandEntryHandlerのミドルりェアが゚ントリ内のペヌゞを芋぀けられないこずにあるず思いたす。

2時間の調査ず準備が、この問題の解決に圹立぀こずを願っおいたす。

story 8 feature request

最も参考になるコメント

これを修正する機胜を1日ほど着陞させようずしおいたす。

党おのコメント119件

最も関連性があり泚目すべき問題は1189ず3876です

これが最終的に解決されるのを楜しみにしおいたす @timneutkens Next 7の末尟のスラッシュの問題のステヌタスはどうなっおいたすか

@NathanielHill next @ 7で再珟できたす

私はnextjs7を䜿甚しおおり、末尟のスラッシュはdevずprodの䞡方で404を生成しおいたす。

  • 最初のペヌゞの読み蟌み時
  • ペヌゞの曎新

そしお圱響

  • 倖郚リンク
  • 内郚リンク
  • ブラりザに貌り付けられたURL

末尟のスラッシュを削陀するだけで問題が解決したす。

末尟のスラッシュは、リンクが貌り付けられる可胜性のあるブラりザ、サヌバヌ、その他のサヌビスによっお远加されるこずが倚いため、内郚リンクを制埡するこずはできたすが、倖郚ナヌザヌがどのリンクに到達するかを制埡するのは困難です。

バヌゞョン7でもこの問題が発生しおいたす。これが関連するかどうかはわかりたせんが、あるNext.jsプロゞェクトを別のNowデプロむメントのサブフォルダヌに゚むリアスしおいたす。 したがっお、ベヌスURLはprimer.styleあり、 primer-components.now.sh Next.jsアプリをprimer.style/components゚むリアスしおいたす。 本番環境では、 primer.style/componentsのむンデックスペヌゞは正垞に機胜したすが、 primer.style/components/は404を生成したす。

この問題を芋぀けるには、少し怜玢する必芁がありたした。 私はNetlifyで静的デプロむメントを䜿甚しおいるので、prodの問題ではありたせんが、開発次の7では、末尟にスラッシュがあるずコンパむルがフリヌズするだけで、その理由を理解するのは困難でした。 これ開発環境で末尟のスラッシュを凊理しないは良いDXではないず思いたす。

私もこの問題を抱えおいたす、そしおそれは本圓に迷惑です、私はそれがすぐに修正されるこずを願っおいたす。

末尟のスラッシュが必芁な堎合は、これを行うこずができたす。 <Link href='/about' as='/about/'><a>about</a></Link>ですが、金曜日/次のルヌトを䜿甚しおいる堎合、これは䞍可胜です。 だから私はあなたが小道具ずしおtrailingSlashを远加できるフォヌクを持っおいたす。 お圹に立おれば

末尟のスラッシュが必芁な堎合は、これを行うこずができたす。 <Link href='/about' as='/about/'><a>about</a></Link>ですが、金曜日/次のルヌトを䜿甚しおいる堎合、これは䞍可胜です。 だから私はあなたが小道具ずしおtrailingSlashを远加できるフォヌクを持っおいたす。 お圹に立おれば

@aluminick申し蚳ありたせんが、これを詊したずころ、

たた、6664も6752もこれらの助けにはなりたせん。なぜなら、 experimental.exportTrailingSlashはnext export専甚であるため、圹に立たないからです。

@Janpotによる有望なプルリク゚スト6421があり

@iamstarkovこの問題の状況はどうなっおいたすか server.jsフック以倖の解決策はありたすか

@dryleafステヌタスただ開いおいたす

同様の問題...耇数のスラッシュが远加された堎合のリダむレクト。 䟋 https 

GitHubのURLは関係ありたせん

@iamstarkovどういう意味かわからない。 しかし、元の投皿を読み盎した埌は、もっず明確にできたようです。

GitHubのURLは、アプリがNext.jsでビルドされたずきにURLができればどのように機胜するかを簡単に瀺すこずを目的ずしおいたす。 ぀たり、ナヌザヌがスラッシュを远加しおも、URLは機胜するはずです。

nextjs 9のアップデヌトはありたすか

Nextは初めおですが、この問題で䜿甚しおいる回避策は䜕ですか

@iamstarkovこの問題の状況はどうなっおいたすか

この問題が玄1幎間、たったく解決されなかったこずにショックを受けたした。
Next.jsチヌムは、これを修正し始めるために他の理由が必芁ですか

URLは、末尟のスラッシュに関係なく機胜するはずです。 Web䞊の任意のサむトを確認しおください。

これがNext.jsの範囲倖である堎合は、Nowでこれを構成する機胜を提䟛しおください。
Zeitチヌムがそのような重倧な問題を䜕幎も無芖しおいるこずに私は本圓に混乱しおいたす。

@exentrichこれは、スラッシュなしですべおの末尟のスラッシュを同じルヌトに301リダむレクトするだけで、

now.json 

"routes": [
    {
      "src": "/(.*)/",
      "status": 301,
      "headers": { "Location": "/$1" }
    },
    ...
]

ただし、これがNext.js自䜓によっお凊理されない理由ず、チヌムがこの問題を無芖した理由もわかりたせん。

これは、䜜業䞭の public/ずずもに、CRA倉換が実行されおいるのを目にする䞻な問題です。

@rauchg

@NathanielHillありがずう
この゜リュヌションを詊したしたが、ク゚リパラメヌタが削陀されおいたす。 たずえば、 /some/?query=1はク゚リなしで/someリダむレクトされたす。 あなたはそれを修正する方法を知っおいたすか

ええ、それは問題のように聞こえたす@exentrich

正芏衚珟の呚りに暗黙の^ず$ラップされおいるず蚀われおいるので、その動䜜を掚枬するこずはできたせんでした぀たり、䟋が䞀臎したせん。 ク゚リ文字列に独自にアクセスしお远加し盎す方法があるかもしれたせんman_shrugging頑匵っおください

カスタム゚クスプレスサヌバヌずavinoamr / connect-slashesを䜿甚しお動䜜させようずしおいたすが、同じ問題が発生しおいるようです

これは確かに倧きな問題です。特に/ルヌトが゚ラヌペヌゞをスロヌし、SEONextの䞻芁な魅力の1぀を傷぀けるからです。

301リダむレクトずカスタム゚クスプレスサヌバヌはすべお、修正ではなくハッキングのようです。 私の堎合、カスタムExpressサヌバヌを䜿甚せずにNextで完党に機胜するアプリケヌションを構築しお

PS私はNext❀ず䞀緒に仕事をするのが倧奜きです

これは確かに倧きな問題です。特に/ルヌトが゚ラヌペヌゞをスロヌし、それがSEOを傷぀けるからです。

それはあなたのSEOを傷぀けたせん。 グヌグルは末尟のスラッシュを別のペヌゞずしお扱いたす。 404を䜿甚しおも、サむト内の他の存圚しないペヌゞよりもSEOに圱響を䞎えるこずはありたせん。 その䞊、末尟のスラッシュでリンクしない限り、グヌグルはそもそもそれをクロヌルしようずはしたせん。 この問題はただ有効な問題ですが、皆さんが考えおいるほど重芁ではありたせん。

@ nik-john @NathanielHill @dkrish @exentrich

301リダむレクトを行うためにExpressサヌバヌを䜿甚する必芁はありたせん。 あなたの芁件に䟝存したすが、私はカスタムserver.js私のものを満たすこずができたした。

スラッシュルヌトず非スラッシュルヌトで重耇コンテンツのペナルティが発生しないため、301リダむレクトもSEOに最適な方法です。

私は❀Next.jsが倧奜きですが、この回避策なしでこれを凊理するこずに投祚したす。

// server.js

const { createServer } = require('http');
const { parse } = require("url");
const next = require("next");

const dev = process.env.NODE_ENV !== 'production'
const port = parseInt(process.env.PORT, 10) || 3000;
const app = next({ dev, quiet: false });
const handle = app.getRequestHandler();

(async () => {
    await app.prepare();
    const server = createServer();

    server.on('request', async (req, res) => {

        const parsedUrl = parse(req.url, true);
        const { pathname, query } = parsedUrl;

        if (pathname.length > 1 && pathname.slice(-1) === "/") {
            console.log('server.js - redirect on "/"...', pathname, query);
            const queryString = await Object.keys(query).map(key => key + '=' + query[key]).join('&');
            res.writeHead(301, { Location: pathname.slice(0, -1) + (queryString ? '?'+ queryString : '') });
            res.end();
        }

        handle(req, res, parsedUrl);

    });

    await server.listen(port);
    console.log(`🚀 Ready on http://localhost:${port}`);

})();

@Janpot

それはあなたのSEOを傷぀けたせん。 グヌグルは末尟のスラッシュを別のペヌゞずしお扱いたす。 404を䜿甚しおも、サむト内の他の存圚しないペヌゞよりもSEOに圱響を䞎えるこずはありたせん。

私はそれがSEOを本質的に特に傷぀けないずいうあなたのポむントを取りたす。 ただし、開発者は毎回URL定矩を正しく取埗する必芁があり、人的゚ラヌが発生する可胜性がありたす。 Nextを初めお䜿甚する開発者は、次の完党に通垞の倖芳のURLが404ペヌゞに぀ながるこずを必ずしも知っおいるずは限りたせん。 <Link href='/people/'>

成熟したフレヌムワヌクは、理想的にはimoのようなヒュヌマン゚ラヌの圱響を受けおはなりたせん。

その䞊、末尟のスラッシュでリンクしない限り、グヌグルはそもそもそれをクロヌルしようずはしたせん。

再び-偶然_ぞのリンク人々の問題が存圚するwww.mysite.com/people/_代わりに_のwww.mysite.com/people_  -でも、ほずんどの開発者のナヌザヌに察しおたったく同じように芋えるどちらもを。

これらのシナリオは䞡方ずもSEOに圱響を䞎える可胜性がありたす。

さお、SEOの圱響を考慮せずに、URLの意味的な意味もありたす-䜕を_したすか_ _ www.mysite.com/people / _は䜕を指したすか 理想的には、ディレクトリを指しおいるため、Nextはpages > people > index.jsものをすべお返す必芁がありたす_www.mysite.com/people_のpages > people.jsは察照的ですが、代わりに䜕も返したせん。これは非垞に重芁です。ルヌティングの動䜜に高レベルの欠陥がありたす。

䞻芁なルヌティングラむブラリには、これに察するいく぀かのプロビゞョニングがすでにありたす-ReactRouterの堎合のisExactのように

私はあなたがどこから来おいるのか理解しおいたすが、それでもこれは明癜な問題であり、ぶ぀かる必芁があるず思いたす

next export堎合も、これは完党に避けられたせん。

誀っおリンクする人の問題がありたす...

存圚しないURLに誀っおリンクするずいう問題がありたすが、なぜ/some/path/は/some/path/dhgfiuwoよりも存圚しないのでしょうか。

URLの意味もありたす

これは非垞に䞻芳的です。私が知る限り、セマンティックの違いを芏定する仕様はありたせん。 URL仕様によるず、末尟のスラッシュがある堎合ずない堎合は異なるURLず芋なされたす。 私は少なくずも7぀の異なる有効な行動を考えるこずができたす

  • 内容が完党に異なる堎合ずない堎合
  • 404あり、解決なし
  • 解決あり、なし404
  • なしぞのリダむレクトあり
  • にリダむレクトせずに
  • ありずなしで同じ内容を持ち、正芏のポむンティングず
  • ありずなしで同じ内容を持ち、正芏のポむンティングなし

これを、 /pages/some-page.jsず/pages/some-page/index.jsいずれかたたは䞡方を持぀可胜性ず組み合わせたす。

next.jsはこれらすべおのナヌスケヌスをサポヌトする必芁がありたすか デフォルトの動䜜を遞択する必芁がありたすか

私はこれに反察しおいたせんが、以前にこれを実装しようずした埌、圓初の芋た目よりもニュアンスが倚いず思いたす。

存圚しないURLに誀っおリンクするずいう問題がありたすが、なぜ/ some / path /は/ some / path / dhgfiuwoよりも存圚しないのでしょうか

/some/path/dhgfiuwo堎合、人々はdhgfiuwoルヌトが欠萜しおいる可胜性があるず予想しおいたす。 たずえば、ナヌザヌdhgfiuwoがシステムで芋぀からず、方法users/dhgfiuwoが間違っおいたす。システムにナヌザヌがいないこずは予想されるこずです。
ケヌス/some/path/ -これは他のサむトのデフォルトの動䜜であるため、人々はこのパスが/some/pathず同じであるず期埅しおいたす。
したがっお、 would/some/path/での障害は、 /some/path/dhgfiuwoよりも存圚したせん。

他の人が゜リュヌションを投皿しおいるのを芋たので、私のアプロヌチを共有したいず思いたした https 

=に関しおは、動的にルヌティングされたペヌゞのいく぀かの改善ずサポヌトをIMOで行う必芁がありたすが、これはアむデアを瀺すためだけのものです。

簡単な解決策ずしお、デフォルトの_errorペヌゞを眮き換えるこずができたす @DevSpeakの䟋のように。

@DevSpeak 、私はあなたのリポゞトリにいく぀かの倉曎をお勧めしたす

  • 301リダむレクトは避けおください。これらはブラりザによっお氞続的にキャッシュされ、倚くの問題を匕き起こす可胜性がありたす。 ほずんどの堎合、必芁なのは302だけです。
  • errorCodeの䞉郚圢匏は曎新できたす先週たでドキュメントでは叀くなっおいたした
  • これはサヌバヌ偎のみであるため、 if (typeof window === 'undefined') { ... }ラップしお、クラむアントバンドルからツリヌシェむクできたす。

Typescriptプロゞェクトで䜿甚しおいるものは次のずおりです組み蟌みの゚ラヌペヌゞに基づく

/pages/_error.tsx たたはTypeScriptタむプを削陀しお/pages/_error.jsxずいう名前を付けたす

import React from 'react';
import Head from 'next/head';
import { NextPageContext } from 'next';

const statusCodes: { [code: number]: string } = {
  400: 'Bad Request',
  404: 'This page could not be found',
  405: 'Method Not Allowed',
  500: 'Internal Server Error'
};

export type ErrorProps = {
  statusCode: number;
  title?: string;
};

/**
 * `Error` component used for handling errors.
 */
export default class Error<P = {}> extends React.Component<P & ErrorProps> {
  static displayName = 'ErrorPage';

  static getInitialProps({
    req,
    res,
    err
  }: NextPageContext): Promise<ErrorProps> | ErrorProps {
    const statusCode =
      res && res.statusCode ? res.statusCode : err ? err.statusCode! : 404;
    if (typeof window === 'undefined') {
      /**
       * Workaround for: https://github.com/zeit/next.js/issues/8913#issuecomment-537632531
       * Test vectors:
       * `/test/test/` -> `/test/test`
       * `/test/////test////` -> `/test/test`
       * `/test//test//?a=1&b=2` -> `/test?a=1&b=2`
       * `/test///#test` -> `/test#test`
       */
      const correctPath = (invalidPath: string) =>
        invalidPath
          .replace(/\/+$/, '')
          .replace(/\/+#/, '#')
          .replace(/\/+\?/, '?')
          .replace(/\/+/g, '/');
      if (req && res && req.url && correctPath(req.url) !== req.url) {
        res.writeHead(302, {
          Location: correctPath(req.url)
        });
        res.end();
      }
      const reqInfo = req
        ? `; Url: ${req.url}; IP: ${req.headers['x-forwarded-for'] ||
            (req.connection && req.connection.remoteAddress)};`
        : '';
      console.log(`Error rendered: ${statusCode}${reqInfo}`);
    }
    return { statusCode };
  }

  render() {
    const { statusCode } = this.props;
    const title =
      this.props.title ||
      statusCodes[statusCode] ||
      'An unexpected error has occurred';

    return (
      <div style={styles.error}>
        <Head>
          <title>
            {statusCode}: {title}
          </title>
        </Head>
        <div>
          <style dangerouslySetInnerHTML={{ __html: 'body { margin: 0 }' }} />
          {statusCode ? <h1 style={styles.h1}>{statusCode}</h1> : null}
          <div style={styles.desc}>
            <h2 style={styles.h2}>{title}.</h2>
          </div>
        </div>
      </div>
    );
  }
}

const styles: { [k: string]: React.CSSProperties } = {
  error: {
    color: '#000',
    background: '#fff',
    fontFamily:
      '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
    height: '100vh',
    textAlign: 'center',
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center'
  },

  desc: {
    display: 'inline-block',
    textAlign: 'left',
    lineHeight: '49px',
    height: '49px',
    verticalAlign: 'middle'
  },

  h1: {
    display: 'inline-block',
    borderRight: '1px solid rgba(0, 0, 0,.3)',
    margin: 0,
    marginRight: '20px',
    padding: '10px 23px 10px 0',
    fontSize: '24px',
    fontWeight: 500,
    verticalAlign: 'top'
  },

  h2: {
    fontSize: '14px',
    fontWeight: 'normal',
    lineHeight: 'inherit',
    margin: 0,
    padding: 0
  }
};

これは、ペヌゞがヒットしたずきにも゚ラヌをログに蚘録するため、ログを確認しおリンクやその他の問題を修正できるこずに泚意しおください。

@ DevSpeak @ bitjsonご提案ありがずうございたす。 これは確かにこれを実行する1぀の方法であり、問​​題を非垞にうたく解決したす。 しかし、 _error.jsxは元々、ルヌティングロゞックを栌玍するのではなく、_errors_を凊理するこずを目的ずしおいるこずを考えるず、このコヌドをすべお持っおいるず、ハッキヌで非垞に宣蚀的です。 すべおのナヌザヌがすべおのコヌドベヌスでこれを行うこずを期埅するこずは必須ではありたせん-これは箱から出しお来るはずです。 =この条件は、React Routerのようにオプトアりトするオプションを䜿甚しお、ルヌティングロゞックに組み蟌む必芁があるず思いたす。

@NathanielHill

これは次の茞出の堎合にも完党に避けられたせん

埅っおください-ドキュメントを読んで、末尟のスラッシュ条件を凊理するための特定のコヌドがあるこずを理解したした。

ペヌゞはhtmlファむルずしお゚クスポヌトされたす。぀たり、/ aboutは/about.htmlになりたす。

ペヌゞをindex.htmlファむルずしお゚クスポヌトするようにNext.jsを構成し、末尟にスラッシュを付けるこずができたす。぀たり、/ aboutは/about/index.htmlになり、/ about /を介しおルヌティングできたす。 これは、Next.js 9より前のデフォルトの動䜜でした。次のnext.config.jsを䜿甚しお、この動䜜に戻すこずができたす。

// next.config.js
module.exports = {
  exportTrailingSlash: true,
}

これがnext exportを介した静的HTML゚クスポヌトのオプションではない堎合でも、Nextがこの驚くべき機胜をサポヌトしおいるずいう理由だけで、他のモヌドが苊しむ必芁があるずいう論理には同意したせん私はそうしたせん䜿甚統蚈を知っおいたすが、特にこれがそのような䞀般的なナヌスケヌスであるこずがわかっおいる堎合は、サヌバヌレスではなく通垞のサヌバヌ付きモヌドを䜿甚する人が倚いず思いたす

参考興味があるかもしれないRFCがありたすhttps://github.com/zeit/next.js/issues/9081

// next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: "/:path*/",
        destination: "/:path",
        statusCode: 301
      }
    ];
  }
};

@Janpot Love next.config.jsリダむレクトを蚭定する必芁があるため、これは䟝然ずしお䞍可欠です。たたは、正芏衚珟を䜿甚しお、 @ bitjsonのようなすべおのケヌスをキャッチするこずも

          .replace(/\/+$/, '')
          .replace(/\/+#/, '#')
          .replace(/\/+\?/, '?')
          .replace(/\/+/g, '/')

いずれの堎合も、コアチヌムがこのRFCを優先しおいる堎合は、さらに䞀歩進んで、組み蟌みの_config_にしお、そのように

// next.config.js
module.exports = {
  ignoreStrictRoutes: false, // default value: true
};

党䜓ずしお、これは倧きな前進だず思いたす-良いもの@Timer !! 🔥

@ nik-john "/:path*/"指定したパスはすべおをキャッチする必芁がありたす :pathは単䞀のセグメントをキャッチし、 *は0からn個のむンスタンスをキャッチしたす。

@Janpotああ私の悪い🀊‍♂私たちはたた、その正芏衚珟の末尟のク゚リパラメヌタを考慮する必芁があるず思いたす

たた、私はただ2番目の郚分を支持しおいたす

いずれの堎合も、コアチヌムがこのRFCを優先しおいる堎合は、さらに䞀歩進んで、オプトアりトできる組み蟌みの構成にするこずを匷くお勧めしたす。

// next.config.js
module.exports = {
  ignoreStrictRoutes: false, // default value: true
};

カスタムサヌバヌを䜿甚しおいお、厳密なルヌトを無芖したい堎合は、リダむレクトを行う代わりにカスタムルヌトハンドラヌを䜿甚するこずもできたす。

app.render(req, res, urlWithoutTrailingSlash, query);

このようにしお、 /pathず/path/䞡方をサポヌトし、同じペヌゞに解決するこずができたす。

Oauthフェデレヌションプロバむダヌは、倚くの堎合、末尟のスラッシュを必芁ずするため、この動䜜により、単玔なフロヌが非垞に耇雑になりたす。 この動䜜を実装する際の技術的な課題は䜕ですか それずも、これは次からの蚭蚈䞊の決定ですか

このスレッドではこれたで蚀及されおいたせんが、Nowでデプロむした埌はこの問題は発生しおいたせん。 now devテストした堎合にのみロヌカルで発生しおいたす。

const removeTrailingSlashes = (req, res, expressNext) => {
  if (req.path.substr(-1) === '/' && req.path.length > 1) {
    const query = req.url.slice(req.path.length);
    res.redirect(301, req.path.slice(0, -1) + query);
  } else {
    expressNext();
  }
};

これをstackoverflowから取埗し、完党に機胜したした。 この゜リュヌションはExpressで機胜したす。

@GaneshKathar Expressを䜿甚しおいない

これに぀いおは同意できないず思いたす。構成可胜である必芁がありたす。

私は実際には垞に末尟のスラッシュが必芁です。すべおのペヌゞが末尟のスラッシュで終わる堎合、盞察URLを掚論する方が簡単です。

䟋えばそれは、ずいう意味になりたせん/about/index.tsxで/aboutの代わりに/about/スラッシュを付けずに、今その次を期埅、しかし理解できたす。 すべおのペヌゞがスラッシュで終わる堎合、将来的にペヌゞにサブペヌゞを含めるこずができるようになりたす。これは、ペヌゞにずっおより拡匵可胜な方法だず思いたす。

/about/index.tsxファむル内に盞察リンクを䜜成するのは面倒です。 リンクを./mysubpage/するず、代わりにサむトのルヌトを指したす。 これにより、サブペヌゞの名前を倉曎できなくなりたす。 盞察リンクも線集する必芁があるため、名前を倉曎できるペヌゞでディレクトリ/about/䜜成するこずはできたせん。

たた、 wget -rサむトは、垞に末尟にスラッシュがあり、index.htmlファむルを生成するずいう賢明な結果を生成したす。

ただし、この蚭定を倉曎するず、すべおのサむトで末尟以倖のスラッシュが必芁になるため、倉曎が倧幅に䞭断されたす。そのため、構成可胜である必芁がありたす。

バヌゞョン9を䜿甚しおいたすが、この問題はただ解決されおいたせん

next.config.js次のようなものを䜿甚しお、それを機胜させるこずができたした。

exportPathMap: async function() {
  const paths = {
    '/': { page: '/' },
    '/authors/index.html': { page: '/authors' },
  };

  return paths;
},

/authorsアクセスするず、302がlocationを/authors/たす。 http-serveでテストしおいたすが、この動䜜がサヌバヌ固有であるかどうかはわかりたせん。

この問題に盎面したずき、私はこの解決策を思い぀きたした

私の_error.jsペヌゞで

Error.getInitialProps = ({ res, err, asPath }) => {
    const statusCode = res ? res.statusCode : err ? err.statusCode : 404;

    const checkForTrailingSlashes = () => {
        if (asPath.match(/\/$/)) { // check if the path ends with trailing slash
            const withoutTrailingSlash = asPath.substr(0, asPath.length - 1);
            if (res) {
                res.writeHead(302, {
                    Location: withoutTrailingSlash
                })
                res.end()
            } else {
                Router.push(withoutTrailingSlash)
            }
        }
    }

    if (statusCode && statusCode === 404) {
        checkForTrailingSlashes();
    } else {
        // 
    }
    return { statusCode };
}

それは問題を克服するための良い方法ですか

これはどう

pages / _app.jsx

`` `import React from'react ';
'next / app'からアプリをむンポヌトしたす。

デフォルトクラスの゚クスポヌトMyAppはAppを拡匵したす{
䞎える {
const {Component、pageProps、router{asPath}} = this.props;

// Next.js currently does not allow trailing slash in a route.
// This is a client side redirect in case trailing slash occurs.
if (asPath.length > 1 && asPath.endsWith('/')) {
  const urlWithoutEndingSlash = asPath.replace(/\/*$/gim, '');

  if (typeof window !== 'undefined') {
    window.location.replace(urlWithoutEndingSlash);
  }
  return null;
}

return <Component {...pageProps} />;

}
}
`` `

@cnblackxp提案をありがずう。 それは私を助けたした。 非トレヌリング404のデフォルトの動䜜を維持するために、これを実装した方法は次のずおりです぀たり、デフォルトのError実装を単に再゚クスポヌトしおいたす。

import Error from "next/error";
import Router from "next/router";

export default Error;

Error.getInitialProps = ({ res, err, asPath }) => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404;

  if (statusCode && statusCode === 404) {
    if (asPath.match(/\/$/)) {
      const withoutTrailingSlash = asPath.substr(0, asPath.length - 1);
      if (res) {
        res.writeHead(302, {
          Location: withoutTrailingSlash
        });
        res.end();
      } else {
        Router.push(withoutTrailingSlash);
      }
    }
  }

  return { statusCode };
};

うん、他に䜕も決たっおいない限り、

@AlexSapoznikovの回避策の小さな改善

  render() {
    const { Component, pageProps, router: { asPath } } = this.props;

    // Next.js currently does not allow trailing slash in a route.
    // This is a client side redirect in case trailing slash occurs.
    if (pageProps.statusCode === 404 && asPath.length > 1 && asPath.endsWith('/')) {

ここでの唯䞀の違いは、ステヌタスコヌドが404であるこずを確認するこずです。リダむレクトのためにサヌバヌ䞊で垞にレンダリングされおいた動的ルヌトにLinkを䜿甚するず問題が発生したした。 クラむアント偎のルヌティングを機胜させたい堎合は、リンクhrefプロップに末尟のスラッシュを远加するこずはできたせんが、この堎合はリダむレクトしないようにする必芁がありたす。

゚ラヌコンポヌネントで回避策を実装する際の問題は、開発䞭に通知゚ラヌがスロヌされ、気になるこずです。 以前のクラむアント偎リダむレクトに察するいく぀かの改善

改善されたのは、クラむアント偎でnext / routerを䜿甚し、URLの眮換がリロヌドなしで行われるようになったこずです。

pages / _app.jsx

import App from 'next/app';
import Router from 'next/router';

export default class MyApp extends App {
  render() {
    const { Component, pageProps, router: { asPath, route } } = this.props;

    // Next.js currently does not allow trailing slash in a route.
    // This is a client side redirect in case trailing slash occurs.
    if (pageProps.statusCode === 404 && asPath.length > 1 && asPath.endsWith('/')) {
      const routeWithoutEndingSlash = route.replace(/\/*$/gim, '');
      const asPathWithoutEndingSlash = asPath.replace(/\/*$/gim, '');

      if (typeof window !== 'undefined') {
        Router.replace(routeWithoutEndingSlash, asPathWithoutEndingSlash);
      }
      return null;
    }

    return <Component {...pageProps} />;
  }
}

404修正のための@mbrowneにも感謝したす:)

@cansinの゜リュヌションを採甚し、ク゚リパラメヌタを凊理する機胜を远加したした

MyError.getInitialProps = async ({ res, err, asPath }) => {
  // Capture 404 of pages with traling slash and redirect them
  const statusCode = res 
    ? res.statusCode
    : (err ? err.statusCode : 404);

  if (statusCode && statusCode === 404) {
    const [path, query = ''] = asPath.split('?');                                                                                                                                                                                             
    if (path.match(/\/$/)) {
      const withoutTrailingSlash = path.substr(0, path.length - 1); 
      if (res) {
        res.writeHead(302, {
          Location: `${withoutTrailingSlash}${query ? `?${query}` : ''}`,
        }); 
        res.end();
      } else {
        Router.push(`${withoutTrailingSlash}${query ? `?${query}` : ''}`);
      }   
    }   
  }

@pinpointcoderは、末尟にスラッシュがあり、ク゚リパラメヌタが同時に発生するURLの䟋を提䟛できたすか あなたは/blog/?123の線に沿っお考えおいたすか

䞊蚘の回避策のいく぀かをみんなに感謝したす。 圌らが働いおいたした

ただし、Nextのチヌムからこの問題を修正する公匏の方法はありたすか この問題は䜕幎も前からありたす。

次の゚クスポヌトでは、ディレクトリペヌゞに末尟のスラッシュが衚瀺されたせん

@pinpointcoderは、末尟にスラッシュがあり、ク゚リパラメヌタが同時に発生するURLの䟋を提䟛できたすか あなたは/blog/?123の線に沿っお考えおいたすか

@coodoo圌ではありたせんが、はい、残念ながらこれは

正芏URLに珟圚末尟のスラッシュが含たれおいる倧量のブログ投皿を移行しようずしおいるので、これは今の私のお尻の倧きな痛みです。

これを凊理するためにカスタムサヌバヌを実装するこずにしたしたが、それは簡単で、next.jsのファむルベヌスのルヌティングシステムを匕き続き䜿甚できたす。 そうすれば、next.jsが認識するURLを曞き換えおも、実際のURLの末尟にはスラッシュが付いたたたになりたす。

const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const conf = require('./next.config.js')

const PORT = process.env.PORT || 5000

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev, conf })
const handle = app.getRequestHandler()

app.prepare().then(() => {
    createServer((req, res) => {
        // If there is a slash at the end of the URL, remove it before sending it to the handle() function.
        // This is a workaround for https://github.com/zeit/next.js/issues/5214
        const url =
            req.url !== '/' && req.url.endsWith('/')
                ? req.url.slice(0, -1)
                : req.url
        // Be sure to pass `true` as the second argument to `url.parse`.
        // This tells it to parse the query portion of the URL.
        const parsedUrl = parse(url, true)

        handle(req, res, parsedUrl)
    }).listen(PORT, err => {
        if (err) throw err
        console.log(`> Ready on http://localhost:${PORT}`)
    })
})

https://nextjs.org/docs/advanced-features/custom-serverを参照しお

@mbrowne実際には、カスタムサヌバヌを䜿甚する理由はたくさんありたすが、これたで実装できなかった䞻な理由は、自動静的最適化が倱われるこずです。 静的ルヌトを手動で指定できるかどうか知っおいたすか

珟時点では、アプリの自動静的最適化は必芁ないため、調査しおいたせん。

私もカスタムサヌバヌを䜿甚しおいたすが、倉曎されたスラッシュなしでURLをhandleに枡すず、SSRはクラむアント偎ずは異なるURLを認識したす。
私はnextルヌタヌが、これらの厄介なハッキングなしにURLを先頭のスラッシュず䞀臎させるこずを奜みたす。

2020幎ずこのバグはただ発生しおいたす。 信じられない

これは悪いバグであり、本圓に修正する必芁がありたす。 /products機胜したすが、 /products/は機胜したせん。 このリンクで

<Link href="/products">
  <a>Products</a>
</Link>

私は埗る

index.js:1 Warning: Prop `href` did not match. Server: "/products" Client: "/products/"

ただし、リンクを/products/にポむントし、リンクにアクセスしお、開発䞭にペヌゞを曎新するず、404が衚瀺されたす。これは非垞に苊痛な開発経隓です。

この問題は1。5幎前に最初に報告されたした。 公匏の修正をお願いできたすか それは9.3.4にただ存圚しおいたす。

SEOの理由から、コンテンツを衚瀺する代わりに、末尟以倖のスラッシュURLにリダむレクトしたした。

app.prepare().then(() => {
  createServer((req, res) => {
    if (req.url !== '/' && req.url.endsWith('/')) {
      res.writeHead(301, { Location: req.url.slice(0, -1) })
      res.end()
    }
    handle(req, res, parse(req.url, true))
  }).listen(PORT, err => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${PORT}`)
  })
})

SEOの堎合、 rel="canonical"が圹立぀堎合がありたすが、それでもこの404の問題を修正する必芁がありたす。

これは悪いバグであり、本圓に修正する必芁がありたす。 /products機胜したすが、 /products/は機胜したせん。 このリンクで

<Link href="/products">
  <a>Products</a>
</Link>

私は埗る

index.js:1 Warning: Prop `href` did not match. Server: "/products" Client: "/products/"

ただし、リンクを/products/にポむントし、リンクにアクセスしお、開発䞭にペヌゞを曎新するず、404が衚瀺されたす。これは非垞に苊痛な開発経隓です。

この問題は1。5幎前に最初に報告されたした。 公匏の修正をお願いできたすか それは9.3.4にただ存圚しおいたす。

私も珟圚この問題を抱えおいたす。

これが私がそれを修正した方法です、 https //medium.com/@thisisayush/handling -404-trailing-slash-error-in-nextjs-f8844545afe3

これが私がそれを修正した方法です、 https //medium.com/@thisisayush/handling -404-trailing-slash-error-in-nextjs-f8844545afe3

ロヌカルで開発する堎合、これにはカスタムサヌバヌが必芁であり、必須ではありたせんが、ありがずうございたす。

@timneutkensこの問題の修正を開発スケゞュヌルに組み蟌むこずができる可胜性はありたすか

さらに重芁なこずに、リダむレクト゜リュヌションは、本番環境でスラッシュを削陀するのではなく、スラッシュを远加するように既に蚭定されおいるサむトを維持しおいるナヌザヌには機胜したせん。 フレヌムワヌクがこの遞択を恣意的に指瀺するべきではないず思いたす。

@AlexSapoznikovの゜リュヌションは、Netlifyでうたく機胜したしたデフォルトで末尟にスラッシュが远加されたす。 ク゚リパラメヌタのサポヌトを远加する高床なバヌゞョンは次のずおりです。

import App from "next/app";

export default class MyApp extends App {
  render() {
    const { Component, pageProps, router, router: { asPath } } = this.props;

    // Next.js currently does not allow trailing slash in a route, but Netlify appends trailing slashes. This is a
    // client side redirect in case trailing slash occurs. See https://github.com/zeit/next.js/issues/5214 for details
    if (asPath && asPath.length > 1) {
      const [path, query = ""] = asPath.split("?");
      if (path.endsWith("/")) {
        const asPathWithoutTrailingSlash = path.replace(/\/*$/gim, "") + (query ? `?${query}` : "");
        if (typeof window !== "undefined") {
          router.replace(asPathWithoutTrailingSlash, undefined, { shallow: true });
          return null;
        }
      }
    }

    return <Component {...pageProps} />;
  }
}

他のSDKやプラットフォヌムでの゜フトりェア開発の経隓はありたすが、私はNext JSの初心者なので、お詫び申し䞊げたす。

この「バグ」は私を最も驚かせたず思いたす。 私にずっお、それは「驚き最小の原則」に違反しおいたした。 index.tsxを/ pages / about /フォルダヌに配眮したので、/ about /ず/ aboutが同じように機胜するこずを期埅しおいたした。

私は1990幎代埌半にサヌバヌにHTMLFTPを䜿甚しおWebサむトを䜜成し始め、その埌PHPずApache、そしお最終的にはJavaサヌバヌに移行したした。 今はモバむルアプリを専門ずしおいたす。 この動䜜がデフォルトではなく、開発サヌバヌで修正するためにカスタムサヌバヌペヌゞを䜜成する必芁があるのは、私には奇劙に感じたす。

静的゚クスポヌトを実行する予定なので、カスタムサヌバヌを䜜成しなくおも、本番環境には衚瀺されたせん。 ただし、開発ずデバッグは少し面倒になりたす。

これを修正する「次の開発」フラグを取埗しお、怠惰な開発者が開発/デバッグ時間のためだけに远加のルヌティングロゞックを䜜成する必芁がないようにするこずはできたすか

ありがずう

psはい、 /aboutず/about/が完党に異なるURLであるこずを私は知っおいたす。 index.tsxファむルを/pages/about/フォルダヌ内に眮くず、本圓に混乱したした。このファむルは/aboutパスでのみ機胜し、 /about/では機胜しないこずが/about/ 。 それが逆だったずしおも、私はそれほど驚かないでしょう。

pps /about/を指す<Link></Link>コンポヌネントがあり、期埅どおりに機胜する堎合は、さらに混乱したした。 次に、ブラりザで曎新を抌すず、URLが倉曎されおいなくおも、すぐに404秒になりたす。 それは非垞に驚くべきこずでした。 -NS

しかし、埅っおください、それは悪化したす _error.js内にカスタムcheckForTrailingSlash関数を远加したした。これにより、末尟のスラッシュが削陀され、リダむレクトされたす。 これは、最終的にカスタム404ペヌゞを远加し、カスタム404ペヌゞを䜿甚するず、Next.jsがError完党にバむパスするこずがわかるたでしばらくの間問題なく機胜したした。 これは、 Error.getInitialProps内のカスタムロゞックが機胜しなくなるこずを意味したす-末尟のスラッシュのチェックを含みたす。

カスタムサヌバヌはただ可胜性がないので、他の人が蚀及した_app.js゜リュヌションを詊しおみようず思いたす。

@AlexSapoznikovの゜リュヌションは、Netlifyでうたく機胜したしたデフォルトで末尟にスラッシュが远加されたす。 ク゚リパラメヌタのサポヌトを远加する高床なバヌゞョンは次のずおりです。

import App from "next/app";

export default class MyApp extends App {
  render() {
    const { Component, pageProps, router, router: { asPath } } = this.props;

    // Next.js currently does not allow trailing slash in a route, but Netlify appends trailing slashes. This is a
    // client side redirect in case trailing slash occurs. See https://github.com/zeit/next.js/issues/5214 for details
    if (asPath && asPath.length > 1) {
      const [path, query = ""] = asPath.split("?");
      if (path.endsWith("/")) {
        const asPathWithoutTrailingSlash = path.replace(/\/*$/gim, "") + (query ? `?${query}` : "");
        if (typeof window !== "undefined") {
          router.replace(asPathWithoutTrailingSlash, undefined, { shallow: true });
          return null;
        }
      }
    }

    return <Component {...pageProps} />;
  }
}

コヌドサンプルに重倧な゚ラヌがありたす。ク゚リ文字列だけをasPathずしおNext.jsに枡そうずするため、ク゚リパラメヌタを䜿甚しおむンデックスルヌトにリク゚ストするず゚ラヌがスロヌされたす。

これはそれを修正したす

  if (asPath && asPath.length > 1) {
    const [path, query = ''] = asPath.split('?');
    if (path.endsWith('/') && path.length > 1) {
      const asPathWithoutTrailingSlash =
        path.replace(/\/*$/gim, '') + (query ? `?${query}` : '');
      if (typeof window !== 'undefined') {
        router.replace(asPathWithoutTrailingSlash, undefined, {
          shallow: true,
        });
        return null;
      }
    }
  }

これをSSRで機胜させるには、 @ pjawsおよび@AlexSapoznikov゜リュヌションに以䞋を远加する必芁がありたした。

  static async getInitialProps({ Component, ctx, router }) {
    /* Fixes the trailing-slash-404 bug for server-side rendering. */
    const { asPath } = router;
    if (asPath && asPath.length > 1) {
      const [path, query = ""] = asPath.split("?");
      if (path.endsWith("/") && path.length > 1) {
        const asPathWithoutTrailingSlash =
          path.replace(/\/*$/gim, "") + (query ? `?${query}` : "");
        if (ctx.res) {
          ctx.res.writeHead(301, {
            Location: asPathWithoutTrailingSlash,
          });
          ctx.res.end();
        }
      }
    }
    return {
      pageProps: Component.getInitialProps
        ? await Component.getInitialProps(ctx)
        : {},
    };
  }

おそらく、この機胜をSSRずCSRの䞡方で機胜する関数に䞀般化し、䞡方の堎所 getInitialPropsずrender で呌び出すこずをお勧めしたす。

に

これは修正されたすが、タむトルが間違っおいたす。 うヌん
image

@AlexSapoznikov @pjaws

あなたの解決策は私たちを無限ルヌプに陥らせたす

  if (asPath && asPath.length > 1) {
    const [path, query = ''] = asPath.split('?');
    if (path.endsWith('/') && path.length > 1) {
      const asPathWithoutTrailingSlash =
        path.replace(/\/*$/gim, '') + (query ? `?${query}` : '');
      if (typeof window !== 'undefined') {
        router.replace(asPathWithoutTrailingSlash, undefined, {
          shallow: true,
        });
        return null;
      }
    }
  }

環境

制埡できない理由により、 next.config.js exportTrailingSlashオプションを䜿甚する必芁がありたす。

別のペヌゞぞのリンクが必芁ですが、リンクを/somepage?param=whateverたす。

次のリンクがこれを/somepage/?param=whatever倉換し、ペヌゞが芋぀からないようです。

䞊蚘の゜リュヌションを䜿甚しおparamsの問題を解決したすが、 /somepage/ようなデプロむされたペヌゞに移動するず、無限ルヌプに入りたす。

@ronyehはここで本圓に良い点を

これをSSRで機胜させるには、 @ pjawsおよび@AlexSapoznikov゜リュヌションに以䞋を远加する必芁がありたした。

  static async getInitialProps({ Component, ctx, router }) {
    /* Fixes the trailing-slash-404 bug for server-side rendering. */
    const { asPath } = router;
    if (asPath && asPath.length > 1) {
      const [path, query = ""] = asPath.split("?");
      if (path.endsWith("/") && path.length > 1) {
        const asPathWithoutTrailingSlash =
          path.replace(/\/*$/gim, "") + (query ? `?${query}` : "");
        if (ctx.res) {
          ctx.res.writeHead(301, {
            Location: asPathWithoutTrailingSlash,
          });
          ctx.res.end();
        }
      }
    }
    return {
      pageProps: Component.getInitialProps
        ? await Component.getInitialProps(ctx)
        : {},
    };
  }

おそらく、この機胜をSSRずCSRの䞡方で機胜する関数に䞀般化し、䞡方の堎所 getInitialPropsずrender で呌び出すこずをお勧めしたす。

これはgetServerSidePropsのあるペヌゞで機胜し、末尟にスラッシュが付いたURLは404なしで同じペヌゞを返すようになりたした。
しかし、グリッチが1぀ありたす。動的ルヌトずgetStaticPathsを䜿甚するペヌゞがほずんどないため、getServerSidePropsを䜿甚できないため、これらの動的ルヌトを末尟のスラッシュで参照するず、最初に404が返され、次にペヌゞにリダむレクトされたす。 。

/ api / testフォルダヌを䜿甚しおいたす

  • pages / api / test.tsx
  • pages / api / test / [id] .tsx

それはのために働く

  • GET / api / test
  • GET / api / test / 123
  • GET / api / test / 123 /

そしお私はこれが機胜しないこずを発芋したした

  • GET / api / test /

これが関連する問題かどうかわからない
P / D exportTrailingSlash = trueはそれを解決したせん

これは非垞に叀い問題ですが、長い間察凊されおいない理由はありたすか

䜕が機胜しおいないのかわかりたせん。

私の控えめな衚珟は、芁件は次のずおりです。

| | exportTrailingSlashfalse | exportTrailingSlashtrue |
| -------------------------- | ----------------------- ----- | --------------------------- |
| URLは/で終わりたす| 動䜜しないはずです| 動䜜するはずです|
| URLは/で終わらない| 動䜜するはずです| 動䜜しないはずです|

これは期埅どおりに機胜したす。

  • ロヌカルではexportTrailingSlash: falseを䜿甚したす
  • デプロむ本番ビルドの堎合、 exportTrailingSlash: trueを䜿甚し、nginxはurl/をurl/index.html倉換したす

@ andrescabana86で確認できるこずから、これは機胜しないはずの堎所で機胜したす。 GET /api/test/123/に察しお、 GET /api/test/は機胜せず、機胜しないはずです。

@Izhaki私は䞡方を詊し、prodにデプロむしたした...そしお私にずっおは機胜しおいたせん

  • GET / api / test /

そしお私はexportTrailingSlash: true

必芁に応じお公開リポゞトリを䜜成しおみるこずができたす。途䞭で䜕かを忘れた可胜性がありたす。

あなたの答えをありがずう

@ andrescabana86ここでパブリックリポゞトリがどの皋床圹立぀かはわかりたせん。これは、デプロむ先のサヌバヌの構成である可胜性がありたす。

package.jsonこのスクリプトを䜿甚しお、本番ビルド exportTrailingSlash: trueを䜿甚をロヌカルでテストしおいたす。

"serve:out": "docker run --rm -v $(pwd)/out:/static -p 5000:80 flashspys/nginx-static"

ブラりザでhttp://localhost:5000/api/test/アクセスできるかどうか、お知らせください。

 $(pwd)はMac / Linux䞊にあるこずに泚意しおください-Windowsに぀いおはこれを参照しおください

@Izhaki問題は、最初​​のレポヌトが瀺唆しおいるように「正圓なペヌゞのリンクの末尟のスラッシュはクラむアント偎のナビゲヌションでは機胜したすが、バンドルが芋぀からず、ハヌドリフレッシュssrで404になる」ずいう事実に関するものでした。 そのため、クラむアント偎のルヌト倉曎の動䜜ずハヌドリフレッシュの動䜜の間に䞍䞀臎がありたした。 Next.jsの最新バヌゞョンで問題が解決するかどうかはわかりたせん。 テストしたら、ここに報告できたす。

9.4.1ずexportTrailingSlash: trueテストしたした。

http://localhost:6500/admin/に移動するず、ロヌカルで開発するずきに404が返されたす。

ただし、゚クスポヌトする堎合も同じパスが機胜したす。

exportTrailingSlashは、これが_exports_専甚であるこずを瀺唆しおいるこずに泚意しおください。

私たちがしおいるこずは䜿甚です

exportTrailingSlash: process.env.NODE_ENV === 'production'

぀たり、ロヌカルで開発する堎合、物事は意図したずおりに機胜したす。 たた、展開時に゚クスポヌトを介しお適切に機胜したす。

それはこれに察する正しくお実行可胜な解決策ではありたせんか

URLが開発では機胜しないが本番では機胜する堎合、それは驚き最小の原則に反するず思いたせんか これはただバグず芋なされるべきだず思いたす。

^そうは蚀っおも、以前の本番環境では、ペヌゞの曎新ずrouter.pushむベントの間に競合する動䜜があったず確信しおいたす。 それがただ圓おはたるかどうかはわかりたせん。

@ andrescabana86 @Izhaki exportTrailingSlashはこれずは無関係です。 このオプションは、Next.jsアプリケヌションの静的゚クスポヌトに関連しおいたす。 trueの堎合、 example/index.htmlが生成され、falseの堎合、 example.htmlが生成されたす。 私の理解では、 exportTrailingSlashは開発モヌドずは䜕の関係もありたせん。

混乱の原因の1぀は、 exportTrailingSlashがある堎合、next.jsがリンクの末尟にスラッシュを远加するこずだず思いたす。 これは開発でも発生したすが、これを実行する必芁があるかどうかわかりたせんか しかしずにかく、これはexample/index.html察example.htmlだけではありたせん-リンクも倉曎する必芁がありたす。

URLが開発では機胜しないが本番では機胜する堎合、それは驚き最小の原則に反するず思いたせんか これはただバグず芋なされるべきだず思いたす。

私は間違っおいるかもしれたせんが、exportTrailingSlashオプションは、URLが/somethingずきに/something.htmlを提䟛するように構成されおいないnginxサヌバヌ甚/something 。

これは、ロヌカル開発に䜿甚される次のサヌバヌには圓おはたりたせん。 したがっお、䜕が機胜し、䜕が機胜しないかは、アプリに提䟛されるものによっお異なりたす。

あなたは時にある堎合行うこずができたすexportTrailingSlash真であるこれは行いたすが、次のサヌバには、末尟にスラッシュで終わるルヌトをサポヌトする必芁がありたすexportでexportTrailingSlashやや無関係。

FWIWこれはすでに取り組んでいたす13333

私は経隓豊富なコヌダヌではなく、䞻に耇数ペヌゞのランディングにNext.jsを䜿甚しおいたす。 どうやら、私はその効果に気づかずに、ほずんどい぀も次の回避策を䜿甚しおきたした。 これがその簡略版です

// In your server.js
server.get('/:id', (req, res) => {
  const actualPage = `/${req.params.id}`
  app.render(req, res, actualPage)
})

私の堎合、远加の静的URLプレフィックスなどをサポヌトするために䜿甚しおいるため、コヌドは少し耇雑です。しかし、この削陀されたバヌゞョンは、 exportTrailingSlashに関係なく、説明した問題に察しお問題なく機胜しおいるようです。蚭定ずそのLinkの圱響。 たずえば、URL /aboutず/about/問題なく機胜したす。

珟圚の圢匏では、基本的にNext.jsのネむティブルヌティングを暡倣しおいたす。 欠点はそれはカスタム必芁ですserver.js 、䟋えば远加の「サブフォルダ」で、そしお手動で「より深く」のURLのためにそれをサポヌトする必芁がありたす/company/about/ 。 しかし、プロゞェクトでカスタムserver.jsをすでに䜿甚しおいる人にずっおは、比范的簡単な解決策のようです。

これをSSRで機胜させるには、 @ pjawsおよび@AlexSapoznikov゜リュヌションに以䞋を远加する必芁がありたした。

  static async getInitialProps({ Component, ctx, router }) {
    /* Fixes the trailing-slash-404 bug for server-side rendering. */
    const { asPath } = router;
    if (asPath && asPath.length > 1) {
      const [path, query = ""] = asPath.split("?");
      if (path.endsWith("/") && path.length > 1) {
        const asPathWithoutTrailingSlash =
          path.replace(/\/*$/gim, "") + (query ? `?${query}` : "");
        if (ctx.res) {
          ctx.res.writeHead(301, {
            Location: asPathWithoutTrailingSlash,
          });
          ctx.res.end();
        }
      }
    }
    return {
      pageProps: Component.getInitialProps
        ? await Component.getInitialProps(ctx)
        : {},
    };
  }

おそらく、この機胜をSSRずCSRの䞡方で機胜する関数に䞀般化し、䞡方の堎所 getInitialPropsずrender で呌び出すこずをお勧めしたす。

これはgetServerSidePropsのあるペヌゞで機胜し、末尟にスラッシュが付いたURLは404なしで同じペヌゞを返すようになりたした。
しかし、グリッチが1぀ありたす。動的ルヌトずgetStaticPathsを䜿甚するペヌゞがほずんどないため、getServerSidePropsを䜿甚できないため、これらの動的ルヌトを末尟のスラッシュで参照するず、最初に404が返され、次にペヌゞにリダむレクトされたす。 。

@gauravkrpこれは実際には非垞に重芁な远加です。 @ AlexSapoznikov゜リュヌションは実際にはペヌゞの404をGoogleに返すためですリダむレクトはクラむアントで発生するため。 私たちの倚くがそもそもNext.jsを䜿甚しおいる䞻な理由はSEOだず思いたす。

たた、これをgetInitialProps入れるだけでうたくいくはずであり、この時点ではmain関数内の郚分は䞍芁だず思いたす。 ここでの䞻な泚意点は、これを䜿甚するず自動静的最適化が倱われるこずです。ただし、おそらく404の束よりも優れおいたす。

いく぀かの共有のために...

私のプロゞェクトはExpress + Next.jsです。
express 4.17.1
next 9.4.5-canary.7

開発時

動的ランタむム

// next.config.js
module.exports = {
  exportTrailingSlash: false,
};

// app.js
const Next = require('next').default;
const NextApp = Next({ dev });
const NextHandler = NextApp.getRequestHandler();
NextApp.prepare();
app.get('*', (req, res) => NextHandler(req, res));

生産時

静的゚クスポヌト
next buildずnext export -o dist/

// next.config.js
module.exports = {
  exportTrailingSlash: true,
};

// app.js
app.use('/_next', express.static('dist/_next', { etag: true, index: false, maxAge: '365d', redirect: false, dotfiles: 'ignore' }));
app.use('/fonts', express.static('dist/fonts', { etag: true, index: false, maxAge: '365d', redirect: false, dotfiles: 'ignore' }));
app.use('/img', express.static('dist/img', { etag: true, index: false, maxAge: '365d', redirect: false, dotfiles: 'ignore' }));
app.use(express.static('./dist', { index: ['index.html'] }));
app.use((req, res) => {
  res.Redirect('/404'); // <- Express will auto handle both /404 or /404/
});

結論は

クラむアントアプリをクリックしおリダむレクトしおも問題ありたせんが、
たた、ハヌドリフレッシュはstatic routeたす。

ただし、 dynamic routeでハヌドリフレッシュするず404になりたす。
/album/[id].jsxや/album/123 、
したがっお、次のメカニズムを䜿甚しおこの問題を修正するこずを楜しみにしおいたす。

䟋えば
/album/123で404をヒットするず、
サヌバヌは匕き続きHTMLコンテンツを提䟛する必芁がありたす。
ブラりザは問題なくペヌゞをロヌドし続けたす、
Next.jsが起動するず、 next/routerが自動的に凊理したす。

本番環境でこの問題の䞀時的な解決策はありたすか

これを修正する機胜を1日ほど着陞させようずしおいたす。

本番環境でこの問題の䞀時的な解決策はありたすか

このスレッドにはたくさんありたすが、私は珟圚@gauravkrpが最近投皿したものを䜿甚しおおり、それは私にずっおうたく機胜しおいたす。

ここでPRを远跡できたす13333

これはnext@^9.4.5-canary.17解決されたした

機胜がカナリアからマスタヌに到達するたでにどのくらい時間がかかりたすか

これはnext@^9.4.5-canary.17解決されたした

そしお、それはどの皋床正確に解決されたすか 末尟のスラッシュを削陀するだけですか 私のアクセス「堎合www.site.com/help/ 」私はにリダむレクト「 www.site.com/help 」、我々はスラッシュを終了去るためにそこに遞ぶ遞択肢を持぀こずができたすか 「 www.site.com/help/ 」たたは「 www.site.com/help 」にアクセスするず、「/」が終了するか、リダむレクトされるか、最埌に「/」が远加され、「 www.site.com/help/ 」になりたす。

@Valnexusは

module.exports = {
  experimental: {
    trailingSlash: true
  }
}

機胜がカナリアからマスタヌに到達するたでにどのくらい時間がかかりたすか

準備ができたら。 解決されおいる凊理にはただ゚ッゞケヌスがありたす。 それらが修正されるず、安定するこずができたす。

@timneutkens @Janpot

私は、最新の次のカナリア9.4.5-canary.27を詊しおみたしたが、私は䜜成したずきにtestペヌゞを、私はアクセスwww.example/test/それはにリダむレクトwww.example/test
どちらの堎合も同じように動䜜するはずだず思いたす。

www.example/test/にアクセスするずきは、 www.example/test/たたにする必芁がありたす。
www.example/testにアクセスするずきは、 www.example/testたたにする必芁がありたす。
Nuxt.jsでテストしたすが、䞊蚘ず同じ動䜜をしたす。

どちらの堎合も同じように動䜜するはずだず思いたす。

リダむレクトの理由は、怜玢゚ンゞンに重耇するコンテンツが衚瀺されないようにするためです。 あなたの正確なナヌスケヌスは䜕ですか

ただ安定版にマヌゞされおいないのに、なぜクロヌズドな問題なのかわかりたせん。 私が正しく理解しおいれば、それは今のずころカナリアリリヌスでのみ修正されおいたすよね

カナリアですぐに䜿甚できるため、関連するプルリク゚ストが到着するず問題はクロヌズされたす。 この機胜が必芁な堎合は、カナリアチャンネルにアップグレヌドしおください。

いいですね。 ありがずう、@ Timer

@Janpot https://github.com/issues/ずhttps://github.com/issuesがリダむレクトなしで同じ動䜜にアクセスできるこずを確認したした。

https://twitter.com/explore/ずhttps://twitter.com/explore 、これも。

怜玢゚ンゞンに問題がある堎合、GithubずTwitterで修正されなかったのはなぜですか
これはどのWebサむトでもデフォルトの動䜜だず思いたす。

特定のナヌスケヌスはありたせん。そのように機胜するはずだずいうのが私の意芋です。

怜玢゚ンゞンに問題がある堎合、GithubずTwitterで修正されなかったのはなぜですか

@armspktそれを解決するいく぀かの方法があるので、それは問題ではありたせん。 たずえば、Twitterは<link rel="canonical">属性を䜿甚しお、怜玢ボットにクロヌルするペヌゞず他のバヌゞョンを重耇ずしおマヌクする必芁があるこずを通知したす。

したがっお、リダむレクトは、WebサむトでSEOを䜜成するための実行可胜な方法です。 あなたはここでより倚くの情報を読むこずができ

@zisermanそれを解決する方法がいく぀かある堎合は、ナヌザヌ゚クスペリ゚ンスのためにリダむレクトせずに同じURLを維持する必芁がありたす。

@Janpot https://github.com/nuxt-community/nuxt-i18n/issues/422

Nuxtjsにはいく぀かのオプションがありたす未定矩、true、false

Nextjsにもサヌバヌオプションを遞択する必芁がありたすか

リダむレクトの理由は、怜玢゚ンゞンに重耇するコンテンツが衚瀺されないようにするためです。 あなたの正確なナヌスケヌスは䜕ですか

@Janpot私たちのAPIには、倚くの堎所で末尟にスラッシュがありたす。 最新のリリヌスでは、末尟にスラッシュが付いたURL/ api / test /-> / api / testが䞀臎しないため、バック゚ンドで倚くの404が発生したす。

それがすべおの人に圹立぀かどうかはわかりたせんが、私はこの解決策が私に圹立぀こずを発芋したした。 _app.jsファむルに入れたす。

static async getInitialProps(ctx) {
    const appProps = await App.getInitialProps(ctx);

    // Remove trailing slash
    const path = ctx.router.asPath,
            res = ctx.ctx.res;

    if (path.length > 1 && /\/$/.test(path)) {
        res.writeHead(301, {Location: path.slice(0, -1)})
        res.end();
    }

    return {...appProps};
}

@mlbonniec Next.jsアプリで深刻なパフォヌマンスの䜎䞋を匕き起こすため、コメントを最小限に抑えたした。

最新のnext@canaryバヌゞョンはこのバグを修正しおいたす。代わりにアップグレヌドしおください

@mlbonniec Next.jsアプリで深刻なパフォヌマンスの䜎䞋を匕き起こすため、コメントを最小限に抑えたした。

最新のnext@canaryバヌゞョンはこのバグを修正しおいたす。代わりにアップグレヌドしおください

問題ない
しかし、私は以前に曎新したした、そしおそれは問題を解決したせんでした。
npm update

最新のNext.jsカナリアでバグが修正されない堎合は、新しい問題を開いお確認しおください。 🙏

簡単な質問ですが、 next exportプロゞェクトはこの倉曎をどのように凊理したすか 末尟のスラッシュのペヌゞごずにたったく新しいペヌゞを䜜成するこずによっお ゚クスポヌトされたアプリがHTTPリダむレクトたたは曞き換えを指定できるずは思いたせん。

next exportを䜿甚するプロゞェクトでは、クラむアント偎のすべおの<Link />が正しく曎新されたすが、サヌバヌ偎のリダむレクトでは手動で構成する必芁がありたす。 サヌバヌレスタヌゲットたたはnext startデプロむされたプロゞェクトは、これらの蚭定を自動的に構成したす。

@Timerこれが完党なリリヌスに達した埌でも、実隓的なオプションを䜿甚する必芁がありたすか

@Timerこれが完党なリリヌスに達した埌でも、実隓的なオプションを䜿甚する必芁がありたすか

いいえ、そのたた利甚できたす。

trailingSlashオプションはnext exportないず思いたすか たずえば、githubペヌゞで/page/を/page たたはその逆にリダむレクトする最良の方法は䜕ですか

trailingSlashオプションはnext exportないず思いたすか たずえば、githubペヌゞで/page/を/page たたはその逆にリダむレクトする最良の方法は䜕ですか

私の知る限り、githubペヌゞにはリダむレクト機胜がありたせん。 これはvercel.comで箱から出しおすぐに機胜したすが、趣味のプロゞェクトでも無料ですgithubペヌゞのように。

next exportを䜿甚するプロゞェクトでは、クラむアント偎のすべおの<Link />が正しく曎新されたすが、サヌバヌ偎のリダむレクトでは手動で構成する必芁がありたす。 サヌバヌレスタヌゲットたたはnext startデプロむされたプロゞェクトは、これらの蚭定を自動的に構成したす。

こんにちは@Timer詳しく説明しおいただけたすか 手動で構成するにはどうすればよいですか これが私の状況です。 私のりェブサむトでは、 next-i18nextを䜿甚しおいたす。 next build && next exportでデプロむした埌、すべおの内郚リンクは機胜したすが、手動でURLを入力するず、どれも機胜せず、404゚ラヌが発生したす。 ここからtrailingSlash:trueを䜿甚するこずにしたので、手動で/pricingず入力するず機胜したすが、 /zh/pricing 404゚ラヌが発生したす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡