![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
now-next-routes
Advanced tools
// /routes.ts
export default {
"users/user": new Route<{ userId: number }>({ page: "/users/user", pattern: "/users/:userId" }),
"users/profile": new Route<{ userId: number }>({ page: "/users/profile", pattern: "/users/:userId/profile" }),
};
// /pages/users.tsx
import routes from "./routes.ts";
const userPageLinkProps = routes["users/user"].getLinkProps({ userId: 1 });
export default () => (
<Link {...userPageLinkProps}>
<a>Go to the first user page</a>
</Link>
);
// $ npx now-next-routes generate routes.ts
// then ... now.json is generated!!
//
// /now.json
{
...
"routes": [
{
"src": "^\\/users\\/([^\\/]+?)\\/?$",
"dest": "/users/user?userId=$1"
},
{
"src": "^\\/users\\/([^\\/]+?)\\/profile\\/?$",
"dest": "/users/profile?userId=$1"
}
]
}
FEATURES | WHAT YOU CAN DO |
---|---|
❤️ Designed for Next.js and ZEIT Now | Don't need to manage routes property in now.json |
🌐 Build for Serverless | Custom servers are not required |
📄 Write once, Manage one file | All you need is write routes to one file |
🎩 Type Safe | You can get errors when missing required dynamic URL parameters |
Next.js has file-system routing, but it does not provide dynamic routing. In the strict sense, it is possible to implement dynamic routing if you adopt custom servers such as Express.js. Famous libraries which provide dynamic routes such as next-routes and nextjs-dynamic-routes require to use custom servers too.
On the other hand, ZEIT that develops and manages Next.js provides FaaS called Now. I definitely think
it is the best way to hosting Next.js apps. Now adopts serverless architecture, so you can deploy Next.js app very easily, all
you need is to write now.json
with @now/next
.
ZEIT recommends to deploy one page on one lambda in order to get benefits of serverless
and @now/next
conforms it automatically. However you need use @now/node
or @now/node-server
if you adopt custom servers.
In other words, to use custom servers in Next.js on Now is bad.
The best way is to use no custom servers and set routes
porperty in now.json
to your application routes, but it has very low
maintainability because you need to write the same route settings twice and complex regular expressions.
now-next-routes was created in order to resolve these issues. now-next-routes provides a command to craete routes
property in
now.json
from a specific route definitions and also provides functions to craete links high type safety.
$ npm install --save-dev now-next-routes
If you use Yarn, use the following command.
$ yarn add --dev now-next-routes
// /routes.ts
import { Route } from "now-next-routes";
export default {
// Index
index: new Route({ page: "/index", pattern: "/" }),
// Users
"users/users": new Route({ page: "/users/users", pattern: "/users" }),
"users/user": new Route<{ userId: number }>({ page: "/users/user", pattern: "/users/:userId" }),
// Users - Comments
"comments/comment": new Route<{ userId: number; commentId: number }>({
page: "/comments/comment",
pattern: "/users/:userId/comments/:commentId",
}),
};
First, you need to define routes using now-next-routes. A point that must be keep in your mind is to export as default value
using export default
syntax.
Route
constructornow-next-routes exports Route
class which provides to create objects for Next.js and Now. A route should be an object which
has a page identifier as key and Route
object as value.
Currently, a constructor of Route
accepts an object which has two properties.
page: string
... A page of Next.js. This is a path of files in /pages
in general.pattern: string
... An actual URL pattern. Dynamic parameters should follow the format :parameterName
.new Route<{ userId: number }>({ page: "/users/user", pattern: "/users/:userId" });
Also the constructor accepts one generic type. This type is to improve type safety when you create links with dynamic
parameters. If a route requires dynamic parameters and your project is written by TypeScript, I recommended to
specify.
The type should be an object literal type and properties should be matched dynamic parameters you write in pattern
.
now-next-routes also provides a command to generate routes for Now.
$ npx now-next-routes generate routes.ts
generate
command generates routes
property of now.json
from a routes file you created like the following.
{
"routes": [
{
"src": "^\\/?$",
"dest": "/index"
},
{
"src": "^\\/users\\/?$",
"dest": "/users/users"
},
{
"src": "^\\/users\\/([^\\/]+?)\\/?$",
"dest": "/users/user?userId=$1"
},
{
"src": "^\\/users\\/([^\\/]+?)\\/comments\\/([^\\/]+?)\\/?$",
"dest": "/comments/comment?userId=$1&commentId=$2"
}
]
}
If now.json
exists, this command overwrite routes
property in it. Otherwise, this command creates now.json
file.
import routes from "./routes.ts";
const userPageLinkProps = routes["users/user"].getLinkProps({ userId: 1 });
const Component = () => (
<Link {...userPageLinkProps}>
<a>Go to the first user page</a>
</Link>
);
An object of Route
class provides getLinkProps
function. This is to create props of built-in <Link>
component provided by
Next.js.
Specifically this function returns an object which has href
and as
properties. So you can also write like the following.
<Link href={userPageLinkProps.href} as={userPageLinkProps.as}>
Router.push()
Router.push()
function provided from next/router
makes you to be possible to move to some pages programmatically. This
function also accepts href
and as
values as arguments, so you can give parameters using getLinkProps()
.
Router.push(userPageLinkProps.href, userPageLinkProps.as);
now-next-routes is designed by TypeScript. So you can create links type safety from routes you crated if you gives generic types when calling constructors.
const userPageLinkProps = routes["users/user"].getLinkProps({ userId: "1" });
^^^^^^
// Type 'string' is not assignable to type 'number'. ts(2322)
import { DynamicParameters } from "now-next-routes";
type Query = DynamicParameters<typeof routes["users/user"]>;
Component.getInitialProps = (ctx) => {
const query = ctx as Query;
const userId = query.user_id;
^^^^^^^
// Property 'user_id' does not exist on type 'Partial<{ userId: number; }>'.
// Did you mean 'userId'? ts(2551)
...
return { userId: query.userId };
};
DynamicParameters
type exported by now-next-routes accepts a type of Route
object. It returns a type of dynamic parameters.
It is helpful for handling queries type safety in getInitialProps
.
now.json
By default, now-next-routes
overwrites or creates now.json
file. It is possible to output as other file when you specify
--input
or --output
option.
# Inputs from a template file and outputs as `now.json` .
$ npx now-next-routes generate --input now.sample.json routes.ts
# Inputs from `now.json` and outputs as a specific file name.
$ npx now-next-routes generate --output now-production.json routes.ts
If your now.json
already has custom routes
property, it is possible to merge generated routes to it and you should use
--merge
option.
$ npx now-next-routes --help
Usage: now-next-routes [options] [command]
Options:
-v, --version output the version number
-h, --help output usage information
Commands:
generate [options] <routes-file> generate routes for now.json
*
generate
$ npx now-next-routes generate --help (06/03 06:45:54)
Usage: generate [options] <routes-file>
generate routes for now.json
Options:
-i, --input <path> now.json file path
-o, --output <path> an output now.json file path
-m, --merge merge into existing "routes" property
-h, --help output usage information
Route
Classconstructor<Parameters>(settings: Settings): Route
new Route<{ userId: number }>({ page: "/users/user", pattern: "/users/:userId" });
Returns a new object of Route
class.
Parameters
... A generic type to specify types of dynamic parameters (for TypeScript).settings: Settings
page: string
... A page file path in /pages
directory of Next.js.pattern: string
... A mapping path pattern. The format :parameterName
will be mapped to dynamic parameters.Route.prototype.getLinkProps(parameters: Parameters): LinkProps<Parameters>
route.getLinkProps({ userId: number });
Returns LinkProps<Parameters>
object.
Parameters
... Types of dynamic parameters you gave to constructor (for TypeScript).LinkProps<Parameters>
href: object
pathname: string
... A base path name. This is a page file path in /pages
in general.query: Partial<Parameters>
... Displayed URL string in web browsers.as: string
... A mapped URL.Route.prototype.createRouteForNow(): object
route.createRouteForNow();
Creates an object for routes
propety in now.json
for ZEIT Now. This method is used in CLI, so you don't need to use this
method in general.
This method will be changed without any notices.
DynamicParameters<T extends Route>
type Parameters = { userId: number };
const route = new Route<Parameters>({ page: "users/user", pattern: "/users/:userId" })
type Query = DynamicParameters<typeof route>; // Partial<{ userId: number }>
Returns a type you gave to a constructor of Route
. A returned type is weak type.
Bug reports and pull requests are welcome on GitHub at https://github.com/jagaapple/now-next-routes. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
Please read Contributing Guidelines before development and contributing.
The library is available as open source under the terms of the MIT License.
Copyright 2019 Jaga Apple. All rights reserved.
FAQs
Dynamic routes for Next.js on Now.
The npm package now-next-routes receives a total of 0 weekly downloads. As such, now-next-routes popularity was classified as not popular.
We found that now-next-routes demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.