Problem
There is Link that transitions to /post/1
.
import Link from 'next/link'
export default () => {
const url = `/post/${1}`
return <Link href={url} />
}
Cannot statically type-check if /post/${pid}
is correct as an internal link.
If the file pages/post/[pid].tsx
does not exist, the page transition will fail.
Solution
Pathpida solves this problem.
Reads pages/
directory in Next.js and automatically generates a type definition file for getting internal links.
For example, if pages/
directory is in the following state
pages/[pid].tsx
pages/blog/[...slug].tsx
pages/index.tsx
the following TypeScript file will be generated automatically.
lib/$path.ts
export const pagesPath = {
_pid: (pid: number | string) => ({
$url: () => ({ pathname: '/[pid]', query: { pid }})
}),
blog: {
_slug: (slug: string[]) => ({
$url: () => ({ pathname: '/blog/[...slug]', query: { slug }})
})
},
$url: () => ({ pathname: '/' })
}
As you can see, pagesPath
property corresponds to a file in pages/
directory.
The object returned by $url
method can be passed directly to next/link
and next/router
.
In the component, you can use it as follows.
import Link from 'next/link'
import { pagesPath } from '../lib/$path'
export default () => {
return <Link href={pagesPath.blog._slug(['a', 'b', 'c']).$url()} />
}
Usage in Next.js
This explanation assumes that Next.js and TypeScript have been set up beforehand.
Install pathpida
and npm-run-all
.
$ yarn add pathpida npm-run-all --dev
package.json
{
"scripts": {
"dev": "run-p dev:*",
"dev:next": "next dev",
"dev:path": "pathpida --watch",
"build": "pathpida && next build"
}
}
Start Next.js and pathpida in monitoring mode with Dev command.
$ yarn dev
$path.ts
file will be automatically created in either utils/
or lib/
directory.
lib/
$path.ts
pages/
_app.tsx
index.tsx
lib/$path.ts
export const pagesPath = {
$url: () => ({ pathname: '/' })
}
If you add more files to pages/
directory, lib/$path.ts
file will be changed.
pagesPath
can be imported and used with next/link
or next/router
.
lib/
$path.ts
pages/
articles/
[id].tsx
users/
[...userInfo].tsx
_app.tsx
index.tsx
components/ActiveLInk.tsx
import Link from 'next/link'
import { useRouter } from 'next/router'
import { pagesPath } from '../lib/$path'
function ActiveLink() {
const router = useRouter()
const handleClick = () => {
router.push(pagesPath.users._userInfo(['mario', 'hello', 'world!']).$url())
}
return <>
<div onClick={handleClick}>Hello</div>
<Link href={pagesPath.articles._id(1).$url()}>
World!
</Link>
</>
}
export default ActiveLink
How to specify a query
You can specify a query just by exporting Query
type in pages/
component.
For example, to create /user?userId={number}
, write the following
pages/user.tsx
export type Query = {
userId: number
}
export default () => <div />
To set a query in another component, write the following
import { pagesPath } from '../lib/$path'
pagesPath.user.$url({ query: { userId: 1 }})
How to specify a hash
Just pass hash as an argument of $url method with any string you like.
#
will be given automatically.
import { pagesPath } from '../lib/$path'
pagesPath.user.$url({ query: { userId: 1 }, hash: 'hoge' })
pagesPath.user.$url({ hash: 'fuga' })
You can also get the file path of public/
directory
If you pass --enableStatic
option to pathpida command, it will read the contents of public/
directory and generate a staticPath client.
package.json
{
"scripts": {
"dev": "run-p dev:*",
"dev:next": "next dev",
"dev:path": "pathpida --enableStatic --watch",
"build": "pathpida --enableStatic && next build"
}
}
If you have JSON and PNG images in public/
public/aa.json
public/bb/cc.png
lib/$path.ts or utils/$path.ts
staticPath
client can get the path string directly instead of $url
method.
pages/index.tsx
import Link from 'next/link'
import { staticPath } from '../lib/$path'
console.log(staticPath.aa_json) // /aa.json
export default () => <img src={staticPath.bb.cc_png} />
Thanks for reading to the end
I'd appreciate it if you could give me a star on GitHub!
pathpida
TypeScript friendly internal link client for Next.js and Nuxt.js.
Breaking change ⚠️
2022/11/25
Since pathpida >= 0.20.0
, removed Sapper support.
2022/02/24
Since pathpida >= 0.18.0
, requires TypeSciprt 3.8 or higher for Type-Only Imports.
Features
- Type safety. Automatically generate type definition files for manipulating internal links in Next.js/Nuxt.js.
- Zero configuration. No configuration required can be used immediately after installation.
- Zero runtime. Lightweight because runtime code is not included in the bundle.
- Support for static files. Static files in public/ are also supported, so static assets can be safely referenced.
- Support for appDir of Next.js 13 Layout.
Table of Contents
- Install
- Command Line Interface Options
- Setup - Next.js
- Usage - Next.js
- Define query - Next.js
- Generate static files path - Next.js
- Setup - Nuxt.js
- Usage - Nuxt.js
- Define query - Nuxt.js
- Generate static files path - Nuxt.js
- License
Install
-
Using npm:
$ npm
…
Top comments (0)