Getting Started
Let’s set up your first Fresh project. To create a new project, run this command:
deno run -Ar jsr:@fresh/init
This will span a short wizard that guides you through the setup, like the project name, if you want to use tailwindcss and if you’re using vscode. Your project folder should look like this:
<project root>
├── components/ # Store other components here. Can be named differently
│ └── Button.tsx
├── islands/ # Components that need JS to run client-side
│ └── Counter.tsx
├── routes/ # File system based routes
│ ├── api/
│ │ └── [name].tsx # API route for /api/:name
│ ├── _app.tsx # Renders the outer <html> content structure
│ └── index.tsx # Renders /
├── static/ # Contains static assets like css, logos, etc
│ └── ...
│
├── client.ts # Client entry file that's loaded on every page.
├── main.ts # The server entry file of your app
├── deno.json # Contains dependencies, tasks, etc
└── vite.config.ts # Vite configuration file
Run the dev
task to launch your app in development mode:
deno task dev
Go to the URL printed in the terminal to view your app.
InfoIf you encounter any problems during setup or development, check the troubleshooting guide for common issues and solutions.
Creating our first route
Let’s create a new about page at /about
. We can do that by adding a new file
at routes/about.tsx
.
import { define } from "../utils.ts";
export default define.page(() => {
return (
<main>
<h1>About</h1>
<p>This is the about page.</p>
</main>
);
});
If we navigate to /about
in the browser we’ll see our newly created page.
Create an island
We’re going to create a countdown component that requires JavaScript to function in the browser.
Create a new file at islands/Countdown.tsx
import { useSignal } from "@preact/signals";
import { useEffect } from "preact/hooks";
export function Countdown(props: { target: string }) {
const count = useSignal(10);
useEffect(() => {
const timer = setInterval(() => {
if (count.value <= 0) {
clearInterval(timer);
}
count.value -= 1;
}, 1000);
return () => clearInterval(timer);
}, []);
if (count.value <= 0) {
return <p>Countdown: 🎉</p>;
}
return <p>Countdown: {count}</p>;
}
Let’s add the countdown to our about page:
import { define } from "../utils.ts";
import { Countdown } from "../islands/Countdown.tsx";
export default define.page(() => {
return (
<main>
<h1>About</h1>
<p>This is the about page.</p>
<Countdown />
</main>
);
});
Now, we can see our countdown in action: