Skip to content
Mighty

Hono

The Hono backend adapter integrates Mighty with your Hono project, allowing you to render Astro components from your Hono code.

Refer to the installation guide to use Mighty in a new project, or an existing one.

Once you are done setting up Mighty in your Hono project, you should have the following structure in place:

  • Directoryastro
    • Directorycomponents
      • Welcome.astro
    • Directorylayouts
      • Layout.astro
    • Directorypages
      • index.astro
  • astro.config.ts
  • tsconfig.astro.json

You can run the development server by using the startServer function:

import { Hono } from "hono";
import { startServer } from "@gomighty/hono";
const app = new Hono();
// ...
startServer(app);

This will start a server that renders Astro components on-demand, with Hot Module Replacement (HMR) included for fast updates.

The server will only start in development (i.e. when NODE_ENV=development), and the startServer function will do nothing in production.

Before using Mighty in production, first build optimized versions of your components:

Terminal window
# build assets with npm
npx @gomighty/hono build

Mighty will now use render optimized Astro components either statically or on-demand, depending on your rendering strategy.

You can use Astro as a rendering engine for your application by returning Astro components from your Hono code.

import { Hono } from "hono";
import { db } from "./lib/db";
import { startServer, render } from "@gomighty/hono";
const app = new Hono();
app.get("/", async (c) => {
const posts = await db.getPosts();
return render(c, "posts.index", { posts });
});
startServer(app);

This will render the following Astro component and pass it the posts prop:

  • Directoryastro
    • Directorypages
      • Directoryposts
        • index.astro

You can then use the posts prop in your Astro component:

resources/astro/pages/posts/index.astro
---
interface Props {
posts: { id: number; title: string; content: string }[];
}
const { posts } = Astro.props;
---
<ul>
{
posts.map((post) => (
<li>
<h2>{post.title}</h2>
<p>{post.content}</p>
</li>
))
}
</ul>

You might want to pass properties to every Astro component, such as the current user or notification content.

To do this, use the share function in your Hono code:

import { Hono } from "hono";
import { db } from "./lib/db";
import { startServer, render, share } from "@gomighty/hono";
const app = new Hono();
app.get("/", async (c) => {
const posts = await db.getPosts();
return render(c, "posts.index", { posts });
});
startServer(app);
share(app, async (c) => {
return {
user: db.getUser(),
};
});

You can use shared properties in your Astro component by using the shared function:

---
import { shared } from "@gomighty/hono";
const { user } = shared<{ user: { id: number; name: string } | undefined }>();
---
{user ? `Welcome back, ${user.name}!` : "Please log in!"}

You can use Astro render context properties, such as Astro.request, just like you would in a standard Astro project.

---
interface Props {
posts: { id: number; title: string; content: string }[];
}
const { posts } = Astro.props;
const isBot =
Astro.request.headers.get("User-Agent")?.startsWith("curl") ?? false;
---
{
isBot ? (
<p>Hey, no scraping!</p>
) : (
<ul>
{posts.map((post) => (
<li>
<h2>{post.title}</h2>
<p>{post.content}</p>
</li>
))}
</ul>
)
}