如何在Next.js静态站点生成时获取URL查询字符串?

lskq00tm  于 2022-11-23  发布在  其他
关注(0)|答案(5)|浏览(254)

我想从Next.js静态站点生成的URL获取查询字符串。
我找到了SSR的解决方案,但我需要SSG的解决方案。
谢谢

x8diyxa7

x8diyxa71#

import { useRouter } from "next/router";
import { useEffect } from "react";

const router = useRouter();

useEffect(() => {
    if(!router.isReady) return;
    const query = router.query;
  }, [router.isReady, router.query]);

这很管用。

hmmo2u0o

hmmo2u0o2#

我找到了一种方法

const router = useRouter()

useEffect(() => {
    const params = router.query
    console.log(params)
}, [router.query])
hgb9j2n6

hgb9j2n63#

正如其他回答所提到的,由于SSG不是在请求时发生的,因此您将无法访问上下文中的查询字符串或cookie,但是有一个解决方案,我在这里写了一篇关于它的短文https://dev.to/teleaziz/using-query-params-and-cookies-in-nextjs-static-pages-kbb
TLDR;
使用中间件将查询字符串编码为路径的一部分,

// middleware.js file
import { NextResponse } from 'next/server'
import { encodeOptions } from '../utils';

export default function middleware(request) {
  if (request.nextUrl.pathname === '/my-page') {
    const searchParams = request.nextUrl.searchParams
    const path = encodeOptions({
      // you can pass values from cookies, headers, geo location, and query string
      returnVisitor: Boolean(request.cookies.get('visitor')),
      country: request.geo?.country,
      page: searchParams.get('page'),
    })

    return NextResponse.rewrite(new URL(`/my-page/${path}`, request.nextUrl))
  }
  return NextResponse.next()
}

然后使静态页面成为接受[path]的文件夹

// /pages/my-page/[path].jsx file
import { decodeOptions } from '../../utils'

export async function getStaticProps({
  params,
}) {
  const options = decodeOptions(params.path)
  return {
    props: {
      options,
    }
  }
}

export function getStaticPaths() {
  return {
    paths: [],
    fallback: true
  }
}

export default function MyPath({ options }) {
  return <MyPage
    isReturnVisitor={options.returnVisitor}
    country={options.country} />
}

编码/解码函数可以是一个简单的JSON。strinfigy

// utils.js
// https://github.com/epoberezkin/fast-json-stable-stringify
import stringify from 'fast-json-stable-stringify'

export function encodeOptions(options) {
  const json = stringify(options)
  return encodeURI(json);
}

export function decodeOptions(path) {
  return JSON.parse(decodeURI(path));
}
xxb16uws

xxb16uws4#

您无权访问getStaticProps中的查询参数,因为它只在构建时在服务器上运行。
但是,您可以在页面组件中使用router.query来检索在客户端的URL中传递的查询参数。

// pages/shop.js

import { useRouter } from 'next/router'

const ShopPage = () => {
    const router = useRouter()
    console.log(router.query) // returns query params object

    return (
        <div>Shop Page</div>
    )
}

export default ShopPage

如果页面没有数据提取方法,则当页面在服务器上预生成时,router.query在页面的第一次加载时将是空对象。
next/router文档中:
queryObject-解析为对象的查询字符串。如果页面没有data fetching requirements,则在预呈现期间它将是空对象。默认为{}
正如@zg10在他的回答中提到的,您可以通过使用useEffect的dependencies数组中的router.isReady属性来解决这个问题。
next/router对象文档中:
isReadyboolean-路由器字段是否已在客户端更新并可供使用。只应在useEffect方法内部使用,而不应在服务器上有条件地呈现。

bweufnob

bweufnob5#

您无权访问SSG的查询字符串(?a=b)(它是静态内容-始终相同-仅在构建时执行)。
但是,如果您 * 必须使用查询字符串变量 *,则可以:
1.仍然在构建时(SSG)或动态(ISR)静态预呈现内容,并通过重写(next.config.js或middleware)处理此路由
1.使用SSR
1.使用CSR(也可以使用SWR

相关问题