Routing

Nijor uses file-based routing. Routes are automatically generated from the files inside the src/pages directory. Each .nijor file inside this directory becomes a route in your application. This approach removes the need to manually configure routes.

Understanding App.js

src/App.js is the entry point of a Nijor application. It is not limited to routing. Nijor applications can also be written without using the router.

Without Routing

If your application does not use routing, you can directly run a Nijor component from App.js. In that case, replace <div id="app"></div> in index.html with <app></app>.


        import App from "@/App.nijor";

        (async () => await App.run('app', 1))();
    

In this example, the App component is rendered directly and all other components are rendered inside the App component.

How Components Run

Internally, all Nijor components are rendered in this way. Every compiled Nijor component exposes a run() method.

The run() method takes two arguments:

name is the component name to target, and num specifies how many matching elements should be replaced.


        Component.run(name, num);
    

The name argument exists because the same component can be imported into different pages using different names.
The num argument tells Nijor how many occurrences of that component should be replaced.

In normal application development, you usually do not need to work with these details directly. They are handled internally by the compiler.

With Routing

When routing is enabled, App.js also initializes the router and provides a place for the compiler to inject route and layout definitions.


        import { Render } from "nijor/core";
        import "nijor/router";

        //@Routes()

        (async () => await Render(document.getElementById('app')))();
    

The //@Routes() comment is used by the compiler. During compilation, it is replaced with the generated route and layout definitions.

Using App.nijor with Routing

If you want all layouts to share common components, you can create App.nijor and use it as the root component of the application.

In that case, replace <div id="app"></div> in index.html with <app></app>.

Then App.js will look like this:


        import { Render } from "nijor/core";
        import "nijor/router";
        import App from "@/App.nijor";

        //@Routes()

        (async () => {
            await App.run('app', 1);
            await Render(document.getElementById('app'));
        })();
    

In this setup, App.nijor is rendered first, and the router then renders layouts and pages inside the #app element defined inside it.

Layouts

Layouts define the shared structure used by pages. Common layout elements include navigation bars, headers, sidebars, footers. Layouts are stored inside src/layouts. Every project must contain a default layout src/layouts/default.nijor because every page is rendered inside a layout.

Layouts use the special attribute n:slot to determine where page content should be rendered. You shouldn't add id to these elements.


        <body>
            <nav>
                <a n:route="/">Home</a>
                <a n:route="/about">About</a>
            </nav>

            <div n:slot></div>
        </body>
    

Pages can specify which layout they should use using the layout attribute on the body element.


        <body layout="dashboard">
            <h1>Dashboard</h1>
        </body>
    

This will use the layout file src/layouts/dashboard.nijor. If the layout attribute is not defined, Nijor will automatically use src/layouts/default.nijor.

Basic Routing

Every file inside src/pages becomes a route.


        src/pages/
            index.nijor
            about.nijor
    

This generates the following routes:


        index.nijor  -> /
        about.nijor  -> /about
    

If a route does not exist, Nijor renders src/pages/404.nijor.

Nested Routes

Folders inside src/pages create nested routes.


        src/pages/
            blog/
                index.nijor
                [slug].nijor
    

This generates the following routes:


        blog/index.nijor   -> /blog
        blog/[slug].nijor  -> /blog/:slug
    

Parameterized Routing

Nijor supports parameterized routing. A dynamic route is created by wrapping the parameter name in square brackets in the file name.


        src/pages/products/[id]/[name].nijor
    

This route can match paths like /products/42/laptop. Pages receive route parameters through params instead of props.


        <body params="{ id, name }">
            <h1>{name}</h1>
            <button on:click="buy('{id}')">Buy {name}</button>
        </body>

        <script>
            function buy(id) {
                // API calls
            }
        </script>
    

Route parameters can be used directly inside script just like other variables. However, route parameters should not be referenced directly inside inline event function calls.

onRoute

Nijor provides an onRoute() helper for running code whenever the current route changes.

The callback receives the current route as its argument. This can be useful for analytics, route-based side effects, or logic that should run after navigation.


        import { onRoute } from "nijor/router";

        onRoute(route => { /* Do something */});
    

Every time the page route changes, the registered callback runs with the updated route.

Navigation

Navigation between routes is done using the n:route attribute on anchor tags. The Nijor compiler converts n:route links into client-side navigation handlers, allowing pages to change without reloading the browser. Using href instead will still work, but it will cause the page to refresh.


        <a n:route="/">Index Page</a> <!--Routing will be smooth ; the page won't refresh-->
        <a href="/">Index Page</a> <!--Routing won't be smooth ; the page will refresh-->
    

Use n:route for navigation within a Nijor application. Use href for external links.

Prefetching

Nijor automatically prefetches routes linked on the page to improve navigation speed. When a link becomes visible in the viewport, its corresponding route is fetched in advance, making page transitions nearly instant.

While prefetching improves performance in most cases, it may not always be desirable, especially for routes with heavy data requirements or limited network conditions.

To disable prefetching for a specific link, use the no-prefetch attribute:


        <a n:route="/products" no-prefetch>Products</a>
    

This ensures that the route is only loaded when the user actually navigates to it.

Metadata

Pages inside the src/pages directory can include a head tag. This tag is used for page metadata such as the document title and meta tags.

The title defined inside head works in both CSR and SSR. Other metadata written inside head is mainly used during SSR.

Route parameters can also be used inside the head tag.


        <head>
            <title>{name} | Product</title>
            <meta name="description" content="Buy  from our store">
        </head>

        <body params="{ id, name }">
            <section>
                <h1>{name}</h1>
                <p>Product ID: {id}</p>
            </section>
        </body>
    

In client-side rendering, Nijor uses the page title from the head tag. Other metadata is primarily useful when server-side rendering is enabled.