Skip to content

Commit

Permalink
Add app directory support (#192)
Browse files Browse the repository at this point in the history
Fixes #170
  • Loading branch information
tatethurston authored Sep 15, 2024
1 parent 5e0c1e3 commit 28fc7b2
Show file tree
Hide file tree
Showing 13 changed files with 443 additions and 81 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Changelog

## 2.2.2

- Adds support for Next.js's `app` directory. `Link` accepts either static routes (no url parameters) or a `RouteLiteral` string, which can be generated by the `route` helper from this library:

```tsx
import { route } from "nextjs-routes";

<Link
href={route({
pathname: "/foos/[foo]",
query: { foo: "bar" },
})}
>
Baz
</Link>;
```

- Add `RouteLiteral` type. This type represents a string that confirmed to be a validated application route and can be passed to `Link` or `useRouter`. This is a TypeScript branded type.

```ts
import { RouteLiteral } from "nextjs-routes";
```

## 2.2.1

- Fix route generation on Windows. See [#187](https://github.com/tatethurston/nextjs-routes/issues/187). Thanks @AkanoCA!
Expand Down
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,17 @@

## What is this? 🧐

`nextjs-routes` makes Next.js's `next/link` and `next/router` routes type safe with zero runtime overhead. `nextjs-routes` scans your `pages` directory and generates route types based on your application's routes.

`nextjs-routes` drops into your existing Next.js application with minimal configuration. You won't have to change any code, unless it finds some broken links!
`nextjs-routes` generates type safe routing utilities from your `pages` and/or `app` directory.

## Notice

If you are using Next.js's App Router you may not need this library. Next provides an [experimental option to generate typed links](https://nextjs.org/docs/app/building-your-application/configuring/typescript#statically-typed-links). Note that at this time, Next's option only works for the `app` directory, and not `pages`. If you want type safety for `pages`, use this library.
If you are using Next.js's App Router you may not need this library. Next provides an [experimental option to generate typed links](https://nextjs.org/docs/app/building-your-application/configuring/typescript#statically-typed-links). Next.js's option only works for the `app` directory, and not `pages`.If you're using the `pages` directory, or you're using the `app` directory and want to use typed objects instead of string interpolation to provide URL parameters, use this library.

## Highlights

🦄 Zero config

💨 Types only -- zero runtime
💨 Types only -- zero runtime (pages directory only).

🛠 No more broken links

Expand Down
15 changes: 11 additions & 4 deletions examples/app/@types/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
// This file will be automatically regenerated when your Next.js server is running.
// nextjs-routes version: 2.2.1
// nextjs-routes version: 2.2.2
/* eslint-disable */

// prettier-ignore
Expand Down Expand Up @@ -37,12 +37,19 @@ declare module "nextjs-routes" {

export type Locale = undefined;

type Brand<K, T> = K & { __brand: T };

/**
* A string that is a valid application route.
*/
export type RouteLiteral = Brand<string, "RouteLiteral">

/**
* A typesafe utility function for generating paths in your application.
*
* route({ pathname: "/foos/[foo]", query: { foo: "bar" }}) will produce "/foos/bar".
*/
export declare function route(r: Route): string;
export declare function route(r: Route): RouteLiteral;

/**
* Nearly identical to GetServerSidePropsContext from next, but further narrows
Expand Down Expand Up @@ -74,7 +81,7 @@ declare module "nextjs-routes" {

// prettier-ignore
declare module "next/link" {
import type { Route } from "nextjs-routes";
import type { Route, RouteLiteral } from "nextjs-routes";;
import type { LinkProps as NextLinkProps } from "next/dist/client/link";
import type {
AnchorHTMLAttributes,
Expand All @@ -89,7 +96,7 @@ declare module "next/link" {
export interface LinkProps
extends Omit<NextLinkProps, "href" | "locale">,
AnchorHTMLAttributes<HTMLAnchorElement> {
href: Route | StaticRoute | Omit<Route, "pathname">
href: StaticRoute | RouteLiteral;
locale?: false;
}

Expand Down
4 changes: 3 additions & 1 deletion examples/app/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Link from "next/link";
import Client from "./client";
import { route } from "nextjs-routes";

export default function Page() {
return (
<>
<Client />
<Link href={{ pathname: "/[store]", query: { store: "tate" } }}>
<Link href="/">Home</Link>
<Link href={route({ pathname: "/[store]", query: { store: "tate" } })}>
Tate's Store
</Link>
</>
Expand Down
15 changes: 11 additions & 4 deletions examples/cjs/types/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
// This file will be automatically regenerated when your Next.js server is running.
// nextjs-routes version: 2.2.1
// nextjs-routes version: 2.2.2
/* eslint-disable */

// prettier-ignore
Expand Down Expand Up @@ -37,12 +37,19 @@ declare module "nextjs-routes" {

export type Locale = undefined;

type Brand<K, T> = K & { __brand: T };

/**
* A string that is a valid application route.
*/
export type RouteLiteral = Brand<string, "RouteLiteral">

/**
* A typesafe utility function for generating paths in your application.
*
* route({ pathname: "/foos/[foo]", query: { foo: "bar" }}) will produce "/foos/bar".
*/
export declare function route(r: Route): string;
export declare function route(r: Route): RouteLiteral;

/**
* Nearly identical to GetServerSidePropsContext from next, but further narrows
Expand Down Expand Up @@ -74,7 +81,7 @@ declare module "nextjs-routes" {

// prettier-ignore
declare module "next/link" {
import type { Route } from "nextjs-routes";
import type { Route } from "nextjs-routes";;
import type { LinkProps as NextLinkProps } from "next/dist/client/link";
import type {
AnchorHTMLAttributes,
Expand All @@ -89,7 +96,7 @@ declare module "next/link" {
export interface LinkProps
extends Omit<NextLinkProps, "href" | "locale">,
AnchorHTMLAttributes<HTMLAnchorElement> {
href: Route | StaticRoute | Omit<Route, "pathname">
href: Route | StaticRoute | Omit<Route, "pathname">;
locale?: false;
}

Expand Down
15 changes: 11 additions & 4 deletions examples/intl/@types/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
// This file will be automatically regenerated when your Next.js server is running.
// nextjs-routes version: 2.2.1
// nextjs-routes version: 2.2.2
/* eslint-disable */

// prettier-ignore
Expand Down Expand Up @@ -40,12 +40,19 @@ declare module "nextjs-routes" {
| "fr"
| "nl-NL";

type Brand<K, T> = K & { __brand: T };

/**
* A string that is a valid application route.
*/
export type RouteLiteral = Brand<string, "RouteLiteral">

/**
* A typesafe utility function for generating paths in your application.
*
* route({ pathname: "/foos/[foo]", query: { foo: "bar" }}) will produce "/foos/bar".
*/
export declare function route(r: Route): string;
export declare function route(r: Route): RouteLiteral;

/**
* Nearly identical to GetServerSidePropsContext from next, but further narrows
Expand Down Expand Up @@ -81,7 +88,7 @@ declare module "nextjs-routes" {

// prettier-ignore
declare module "next/link" {
import type { Route } from "nextjs-routes";
import type { Route } from "nextjs-routes";;
import type { LinkProps as NextLinkProps } from "next/dist/client/link";
import type {
AnchorHTMLAttributes,
Expand All @@ -96,7 +103,7 @@ declare module "next/link" {
export interface LinkProps
extends Omit<NextLinkProps, "href" | "locale">,
AnchorHTMLAttributes<HTMLAnchorElement> {
href: Route | StaticRoute | Omit<Route, "pathname">
href: Route | StaticRoute | Omit<Route, "pathname">;
locale?: Locale | false;
}

Expand Down
15 changes: 11 additions & 4 deletions examples/typescript/types/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
// This file will be automatically regenerated when your Next.js server is running.
// nextjs-routes version: 2.2.1
// nextjs-routes version: 2.2.2
/* eslint-disable */

// prettier-ignore
Expand Down Expand Up @@ -39,12 +39,19 @@ declare module "nextjs-routes" {

export type Locale = undefined;

type Brand<K, T> = K & { __brand: T };

/**
* A string that is a valid application route.
*/
export type RouteLiteral = Brand<string, "RouteLiteral">

/**
* A typesafe utility function for generating paths in your application.
*
* route({ pathname: "/foos/[foo]", query: { foo: "bar" }}) will produce "/foos/bar".
*/
export declare function route(r: Route): string;
export declare function route(r: Route): RouteLiteral;

/**
* Nearly identical to GetServerSidePropsContext from next, but further narrows
Expand Down Expand Up @@ -76,7 +83,7 @@ declare module "nextjs-routes" {

// prettier-ignore
declare module "next/link" {
import type { Route } from "nextjs-routes";
import type { Route } from "nextjs-routes";;
import type { LinkProps as NextLinkProps } from "next/dist/client/link";
import type {
AnchorHTMLAttributes,
Expand All @@ -91,7 +98,7 @@ declare module "next/link" {
export interface LinkProps
extends Omit<NextLinkProps, "href" | "locale">,
AnchorHTMLAttributes<HTMLAnchorElement> {
href: Route | StaticRoute | Omit<Route, "pathname">
href: Route | StaticRoute | Omit<Route, "pathname">;
locale?: false;
}

Expand Down
15 changes: 11 additions & 4 deletions packages/e2e/@types/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
// This file will be automatically regenerated when your Next.js server is running.
// nextjs-routes version: 2.2.1
// nextjs-routes version: 2.2.2
/* eslint-disable */

// prettier-ignore
Expand Down Expand Up @@ -38,12 +38,19 @@ declare module "nextjs-routes" {

export type Locale = undefined;

type Brand<K, T> = K & { __brand: T };

/**
* A string that is a valid application route.
*/
export type RouteLiteral = Brand<string, "RouteLiteral">

/**
* A typesafe utility function for generating paths in your application.
*
* route({ pathname: "/foos/[foo]", query: { foo: "bar" }}) will produce "/foos/bar".
*/
export declare function route(r: Route): string;
export declare function route(r: Route): RouteLiteral;

/**
* Nearly identical to GetServerSidePropsContext from next, but further narrows
Expand Down Expand Up @@ -75,7 +82,7 @@ declare module "nextjs-routes" {

// prettier-ignore
declare module "next/link" {
import type { Route } from "nextjs-routes";
import type { Route } from "nextjs-routes";;
import type { LinkProps as NextLinkProps } from "next/dist/client/link";
import type {
AnchorHTMLAttributes,
Expand All @@ -90,7 +97,7 @@ declare module "next/link" {
export interface LinkProps
extends Omit<NextLinkProps, "href" | "locale">,
AnchorHTMLAttributes<HTMLAnchorElement> {
href: Route | StaticRoute | Omit<Route, "pathname">
href: Route | StaticRoute | Omit<Route, "pathname">;
locale?: false;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/e2e/next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
2 changes: 1 addition & 1 deletion packages/nextjs-routes/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nextjs-routes",
"version": "2.2.1",
"version": "2.2.2-rc.1",
"description": "Type safe routing for Next.js",
"license": "MIT",
"author": "Tate <[email protected]>",
Expand Down
Loading

0 comments on commit 28fc7b2

Please sign in to comment.