Waku

将 nuqs 与 Waku 集成

Waku 被支持作为社区贡献的适配器。

步骤 1:添加适配器代码

自定义适配器 API 尚未稳定,未来可能在小版本或补丁发布中发生变化(不符合 SemVer)。

app/nuqs-waku-adapter.tsx
"use client";

import {
  type unstable_AdapterOptions as AdapterOptions,
  unstable_createAdapterProvider as createAdapterProvider,
  renderQueryString,
} from "nuqs/adapters/custom";
// import { useRouter_UNSTABLE as useRouter } from "waku";
// if waku v0.22 or later:
import { useRouter } from "waku";

function useNuqsAdapter() {
  const { path, query, push, replace } = useRouter();
  const searchParams = new URLSearchParams(query);
  const updateUrl = (search: URLSearchParams, options: AdapterOptions) => {
    const query = renderQueryString(search);
    const url = path + query + location.hash;
    if (options.shallow) {
      options.history === "push"
        ? history.pushState(null, "", url)
        : history.replaceState(null, "", url);
    } else {
      const updateMethod = options.history === "push" ? push : replace;
      // bypass waku's typesafe route check by using `as never`
      updateMethod(url as never);
    }
    // Waku router does not scroll unless the pathname changes
    if (options.scroll) {
      window.scrollTo(0, 0);
    }
  };
  return {
    searchParams,
    updateUrl,
  };
}

export const NuqsAdapter = createAdapterProvider(useNuqsAdapter);

步骤 2:包装你的根布局

通过包装 {children} 组件,将适配器集成到 _layout.tsx 或 _root.tsx 文件中:

app/_layout.tsx
import { Suspense, type ReactNode } from 'react';

import { NuqsAdapter } from './nuqs-waku-adapter'

type LayoutProps = { children: ReactNode };

export default async function Layout({ children }: LayoutProps) {
  return (
      <>
        <NuqsAdapter>
          <Suspense>
            {children}
          </Suspense>
        </NuqsAdapter>
      </>
  );
}

export const getConfig = async () => {
  return {
    render: 'dynamic',
    // render: 'static', // works but can cause hydration warnings
  } as const;
};