Aleph.js has a file-system based router built on the concept of pages.
When a file (.js, .jsx, .ts, .tsx, and .mjs) is added to the pages directory, it is automatically available as a route.

Index Routes

The router will automatically route files named index to the root of the directory.

  • pages/index.tsx/
  • pages/blog/index.tsx/blog

Dynamic Routes

To match a dynamic segment, you can use bracket syntax or start the segment with $:

  • pages/blog/[slug].tsx/blog/:slug (/blog/hello-world)
  • pages/[username]/settings.tsx/:username/settings (/foo/settings)
  • pages/post/[...all].tsx/post/* (/post/2020/id/title)

Nested Routes

Aleph.js supports nested route structures like:

  • pages/blog.tsx
  • pages/blog/[slug].tsx

In the example, routes in /blog/:slug will be rendered under the pages/blog.tsx, that is useful to create a layout for pages:

import React from ''
import BlogHeader from '../components/blog-header.tsx'

export default function Blog({ Page, pageProps }) {
  return (
      <BlogHeader />
      <Page ...pageProps />

RouterURL Object

To access the RouterURL object, you can use the useRouter hook in a component:

import { useRouter } from ''

// hypothetically current location patname is '/post/hello-world?theme=dark'
export default function Component({ href, children }) {
  const {
    basePath,      // string, should be '/'
    locale,        // string, should be 'en'
    defaultLocale, // string, should be 'en'
    locales,       // string[], should be ['en']
    pathname,      // string, should be '/post/hello-world'
    routePath,     // string, should be '/post/[slug]'
    params,        // object, should be {slug: 'hello-world'}
    query,         // URLSearchParams, `query.get('theme')` should be 'dark'
  } = useRouter()

  return <p>current pathname: {pathname}</p>

I18N routing

Aleph.js don't provide I18N function directly, but the routing supports the locale prefix. You need to config the locales in aleph.config.ts:

import type { Config } from ''

export default <Config>{
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'zh-CN'],

In the above example, all the routes will match paths with the 'zh-CN' prefix, even if zh-CN don't exist in the pages dir:

  • pages/index.tsx/ and /zh-CN (pathname is /)
  • pages/blog.tsx/blog and /zh-CN/blog (pathname is /blog)

Now you can access locale in the Router object using the useRouter hook:

import React from ''
import { useRouter } from ''

export default function Page() {
  const { locale } = useRouter()

  if (locale === 'zh-CN') {
    return <h1>你好 :)</h1>
  return <h1>Hello :)</h1>

And the build command (SSG) will generate all the locale pages from the locale list.