メインコンテンツまでスキップ

Pathpida と Next.js

pathpida logopathpida logo

TypeScript friendly internal link client for Next.js.

Star

特徴

  • 型安全。Next.js で内部リンクを取り扱うための型定義ファイルを自動生成します。
  • 設定不要。設定を必要とせず、インストール後すぐに使用できます。
  • 実行時負荷無し。ランタイムコードがバンドルに含まれないので軽量です。

インストール

  • npm を使用:

    $ npm install pathpida --save-dev
  • Yarn を使用:

    $ yarn add pathpida --dev

セットアップ

package.json

{
"scripts": {
"dev:pathpida": "pathpida --watch",
"build:client": "pathpida && aspida && next build",
"build:types": "pathpida && aspida && npm run build:frourio --prefix server"
}
}

使い方

pages/index.tsx
pages/post/create.tsx
pages/post/[pid].tsx
pages/post/[...slug].tsx

utils/$path.ts // Generated automatically by pathpida

pages/index.tsx

import Link from 'next/link';
import { pagesPath } from '~/utils/$path';

console.log(pagesPath.post.create.$url()); // { pathname: '/post/create' }
console.log(pagesPath.post._pid(1).$url()); // { pathname: '/post/[pid]', query: { pid: 1 }}
console.log(pagesPath.post._slug(['a', 'b', 'c']).$url()); // { pathname: '/post//[...slug]', query: { slug: ['a', 'b', 'c'] }}

export default () => {
const onclick = useCallback(() => {
router.push(pagesPath.post._pid(1).$url());
}, []);

return (
<>
<Link href={pagesPath.post._slug(['a', 'b', 'c']).$url()} />
<div onclick={onclick} />
</>
);
};

クエリの定義

pages/post/create.tsx

export type Query = {
userId: number;
name?: string;
};

export default () => <div />;

pages/post/[pid].tsx

export type OptionalQuery = {
limit: number;
label?: string;
};

export default () => <div />;

pages/index.tsx

import Link from 'next/link';
import { pagesPath } from '~/utils/$path';

console.log(pagesPath.post.create.$url({ query: { userId: 1 } })); // { pathname: '/post/create', query: { userId: 1 }}
console.log(pagesPath.post.create.$url()); // type error
console.log(pagesPath.post._pid(1).$url()); // { pathname: '/post/[pid]', query: { pid: 1 }}
console.log(pagesPath.post._pid(1).$url({ query: { limit: 10 }, hash: 'sample' })); // { pathname: '/post/[pid]', query: { pid: 1, limit: 10 }, hash: 'sample' }

export default () => {
const onclick = useCallback(() => {
router.push(pagesPath.post._pid(1).$url());
}, []);

return (
<>
<Link href={pagesPath.post._slug(['a', 'b', 'c']).$url()} />
<div onclick={onclick} />
</>
);
};

静的パスの生成

package.json

{
"scripts": {
"dev:pathpida": "pathpida --enableStatic --watch",
"build:client": "pathpida --enableStatic && aspida && next build",
"build:types": "pathpida --enableStatic && aspida && npm run build:frourio --prefix server"
}
}
pages/index.tsx
pages/post/create.tsx
pages/post/[pid].tsx
pages/post/[...slug].tsx

public/aa.json
public/bb/cc.png

utils/$path.ts // Generated automatically by pathpida

pages/index.tsx

import Link from 'next/link';
import { pagesPath, staticPath } from '~/utils/$path';

console.log(staticPath.aa_json); // /aa.json

export default () => {
return (
<>
<Link href={pagesPath.post._slug(['a', 'b', 'c']).$url()} />
<img src={staticPath.bb.cc_png} />
</>
);
};