Basic Routing
Learn the fundamentals of File-System Based Routing in JopiJS. How to map folders to URLs and create your first pages and APIs.
JopiJS relies on a powerful concept called "File-System Based Routing". The structure of your folders is the structure of your website.
In this tutorial, we will build a small site together to understand how it works.
Prerequisites:
You must have a JopiJS project initialized with the minimal template (see here for instructions).
1. Creating the Homepage
We want to create the main page of your site, accessible at http://localhost:3000/.
Step 1: Create the Workspace
The minimal template is empty. We need to create our working module.
- Go to
src/. - Create a folder named
mod_app. - Inside, create a folder named
@routes.
Step 2: Add the file
Inside the @routes folder (at the root), create a file named page.tsx.
Copy this code:
import { usePageTitle } from "jopijs/ui";
export default function HomePage() {
usePageTitle("My Homepage");
return (
<div className="p-10">
<h1 className="text-4xl text-blue-600">Welcome Home!</h1>
<p className="text-lg">This is the root page of your application.</p>
<p>Go to <a href="/hello" className="underline text-blue-500">/hello</a> to test the API.</p>
</div>
);
}🎨 Styling Note: In this tutorial, we use Tailwind CSS for styling. JopiJS is pre-configured to handle Tailwind out of the box, so you can start using utility classes immediately.
Step 3: Start the Server
Run the following command in your terminal:
npm run start:dev_serverThis starts the development server with automatic restart. The server will restart when you modify any file in the src/ folder.
Open your browser at http://localhost:3000/. Your homepage is live!
2. Creating an Interactive Page
Now let's create a new page at /hello. This page will feature a form allowing you to enter your name, send it to the server, and display the greeting received in response.
In JopiJS, a single folder can handle both the display and the data processing.
Step 1: Create the folder
Inside @routes, create a new folder named hello.
path: src/mod_app/@routes/hello/
Step 2: Create the Page (Client Side)
Inside this folder, create a file named page.tsx.
This page will accept a name and send it to the server using the fetch API.
"use client";
import React from "react";
export default function HelloPage() {
// Our states, to store the name and the response.
const [name, setName] = React.useState("");
const [response, setResponse] = React.useState("");
// Our function to send the name to the server.
//
async function sendGreeting() {
// We POST data to the current URL
const res = await fetch(window.location.href, {
method: "POST",
body: JSON.stringify({ name }),
});
const data = await res.json();
setResponse(data.message);
}
// A simple form:
// - Allows to enter a name
// - Displays the server response
//
return (
<div className="p-10">
<h1 className="text-2xl mb-4">Say Hello</h1>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter your name"
className="border p-2 w-full mb-4 rounded"
/>
<button
onClick={sendGreeting}
className="bg-blue-600 text-white p-2 w-full rounded"
>
Send to Server
</button>
{response && (
<div className="mt-4 p-4 bg-green-100 rounded">
{response}
</div>
)}
</div>
);
}Step 3: Create the API (The Backend)
Now we need to handle that POST request.
In JopiJS, page.tsx handles the display, and onPOST.ts handles the data submission.
Inside our current folder (src/mod_app/@routes/hello/) create a file named onPOST.ts.
import { JopiRequest } from "jopijs";
export default async function(req: JopiRequest) {
// 1. Read the JSON body sent by the browser
const body = await req.req_getBodyAsJson();
// 2. Return a custom greeting
return req.res_jsonResponse({
message: "Hello " + body.name + " from JopiJS!"
});
}Step 4: Test It
- Go to
http://localhost:3000/hello. - Type your name (e.g., "Tony").
- Click "Send to Server".
- You should see "Hello Tony from JopiJS!" appear.
You just built a complete full-stack feature (Frontend + Backend) in a single folder!