saus icon indicating copy to clipboard operation
saus copied to clipboard

Support file-based routing

Open aleclarson opened this issue 4 years ago • 2 comments

Inside your src/node/routes.ts module:

import { findPages } from 'saus'

// The "/**" suffix is optional.
findPages('./pages/**', ['*.mdx?', '*.njk'])

Paths are relative to the project root, so the findRoutes call above would work with the following file structure:

my-app/
├─ pages/
│  ├─ index.mdx
│  ├─ users/
│  │  ├─ [id].njk
├─ src/
│  ├─ render.ts
│  ├─ node/
│  │  ├─ routes.ts

Renderers would receive the file content in string form, passed by the module.default argument.

We would also expose a fileType property, which allows a renderer to handle multiple file types if so desired.

Renderers could still target specific routes (via route paths) and route parameters could be used to parse out parts of the filename. In the example above, a page named ./pages/foo/index.mdx would be served for the /foo and /foo/ URLs.

Dynamic routes

Naturally, square brackets in a page's filename would indicate route parameters. For example, a page named…

./pages/users/[id].njk

…would be served by the /users/:id route. Although, these pages would not be eligible for pre-rendering (until we come up with a suitable API, of course).

Front matter

Lastly, a helper for parsing front matter from a page would be exported by the saus module.

import { extractFrontMatter } from 'saus'

render((module) => {
  const metadata = extractFrontMatter(module)
  // return [...]
})

Calling it would update the content of module.default, removing the parsed front matter.

aleclarson avatar Oct 17 '21 23:10 aleclarson

This is now relatively straight-forward in userland, thanks to the generateRoute function.

Moving this proposal (for builtin file-crawling helpers) to the backlog for now

aleclarson avatar Mar 14 '22 21:03 aleclarson

(Note: Make sure to enforce case-sensitivity in development, like Next does)

aleclarson avatar Oct 28 '22 01:10 aleclarson