diff --git a/README.md b/README.md
index 4322b79..fe31fb0 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,20 @@
# HonoX
-HonoX is a simple and fast meta framework for creating Web APIs and websites with Server-Side Rendering - (formerly _Sonik_). It stands on the shoulders of giants; built on [Hono](https://hono.dev/), [Vite](https://hono.dev/), and UI libraries.
+**HonoX** is a simple and fast meta framework for creating websites and Web APIs with Server-Side Rendering - (formerly _[Sonik](https://github.com/sonikjs/sonik)_). It stands on the shoulders of giants; built on [Hono](https://hono.dev/), [Vite](https://hono.dev/), and UI libraries.
**Note**: _HonoX is currently in a "beta stage". There will be breaking changes without any announcement. Don't use it in production. However, feel free to try it in your hobby project and give us your feedback!_
## Features
-- **File-based routing** - Now, you can create a large app by separating concerns.
-- **Fast SSR** - Supports only Server-Side Rendering. Rendering is ultra-fast thanks to Hono.
-- **No JavaScript** - By default, there's no need for JavaScript. Nothing loads.
-- **Any UI library** - You can use any UI library besides hono/jsx, such as React, Preact, etc.
-- **Island hydration** - If you want interactions, create an island. JavaScript is hydrated only for that island.
-- **Easy API creation** - You can create APIs using Hono's syntax.
-- **Middleware** - It works just like Hono, so you can use many of Hono's middleware.
+- **File-based routing** - You can create a large app by separating concerns.
+- **Fast SSR** - Rendering is ultra-fast thanks to Hono.
+- **BYOR** - You can bring your own renderer, not only one using hono/jsx.
+- **Island hydration** - If you want interactions, create an island. JavaScript is hydrated only for it.
+- **Middleware** - It works as Hono, so you can use a lot of Hono's middleware.
## Get Started - Basic
-Let's create a basic HonoX application using hono/jsx as a renderer.
+Let's create a basic HonoX application using hono/jsx as a renderer. This application has no client JavaScript and renders JSX on the server side.
### Project Structure
@@ -56,7 +54,7 @@ export default defineConfig({
A server entry file is required. The file is should be placed at `app/server.ts`. This file is first called by the Vite during the development or build phase.
-In the entry file, simply initialize your app using the `createApp()` function. app will be an instance of Hono, so you can utilize Hono's middleware and the `showRoutes()` in `hono/dev`.
+In the entry file, simply initialize your app using the `createApp()` function. `app` will be an instance of Hono, so you can use Hono's middleware and the `showRoutes()`in`hono/dev`.
```ts
// app/server.ts
@@ -72,7 +70,11 @@ export default app
### Routes
-Each route should return an array of `Handler | MiddlewareHandler`. You can write a route for a GET request with `default export`.
+There are three ways to define routes.
+
+#### 1. `createRoute()`
+
+Each route should return an array of `Handler | MiddlewareHandler`. `createRoute()` is a helper function to return it. You can write a route for a GET request with `default export`.
```tsx
// `createRoute()` helps you create handlers
@@ -113,7 +115,7 @@ export default createRoute((c) => {
})
```
-#### Using Hono instance
+#### 2. Using Hono instance
You can create API endpoints by exporting an instance of the Hono object.
@@ -134,9 +136,19 @@ app.get('/:name', (c) => {
export default app
```
+#### 3. Just return JSX
+
+Or simply, you can just return JSX.
+
+```tsx
+export default function Home() {
+ return
Welcome!
+}
+```
+
### Renderer
-You can define Hono's Renderer - i.e. the middleware that does `c.setRender()` - by writing it in `_renderer.tsx`.
+Define your renderer - the middleware that does `c.setRender()` - by writing it in `_renderer.tsx`.
Before writing `_renderer.tsx`, write the Renderer type definition in `global.d.ts`.
@@ -155,7 +167,7 @@ declare module 'hono' {
}
```
-The JSX Renderer middleware allows you to define a Renderer as follows:
+The JSX Renderer middleware allows you to create a Renderer as follows:
```tsx
// app/routes/_renderer.tsx
@@ -209,7 +221,7 @@ export default handler
## Get Started - with Client
-Let's create an application that includes a client side. Here, we will use React as the UI library.
+Let's create an application that includes a client side. Here, we will use hono/jsx/dom.
### Project Structure
@@ -231,7 +243,86 @@ The below is the project structure of a minimal application including a client s
└── vite.config.ts
```
-### React Renderer
+### Renderer
+
+This is a `_renderer.tsx` which will load the `/app/client.ts` entry file for the client. It can also load the JavaScript file for the production according to the variable `import.meta.env.PROD`.
+
+```tsx
+// app/routes/_renderer.tsx
+import { jsxRenderer } from 'hono/jsx-renderer'
+
+export default jsxRenderer(({ children }) => {
+ return (
+
+
+
+
+ {import.meta.env.PROD ? (
+
+ ) : (
+
+ )}
+
+ {children}
+
+ )
+})
+```
+
+### Client Entry File
+
+A client side entry file should be in `app/client.ts`. Simply, write `createClient()`.
+
+```ts
+// app/client.ts
+import { createClient } from 'honox/client'
+
+createClient()
+```
+
+### Interactions
+
+Function components placed in `app/islands/*` are also sent to the client side. For example, you can write interactive component such as the following counter:
+
+```tsx
+// app/islands/counter.tsx
+import { useState } from 'hono/jsx'
+
+export default function Counter() {
+ const [count, setCount] = useState(0)
+ return (
+
+
Count: {count}
+
+
+ )
+}
+```
+
+When you load the component in a route file, it is rendered as Server-Side rendering and JavaScript is also send to the client-side.
+
+```tsx
+// app/routes/index.tsx
+import { createRoute } from 'honox/factory'
+import Counter from '../islands/counter'
+
+export default createRoute((c) => {
+ return c.render(
+
+
Hello
+
+
+ )
+})
+```
+
+## BYOR - Bring Your Own Renderer
+
+You can bring your own renderer using a UI library like React, Preact, Solid, or others.
+
+**Note**: We cannot provide technical support for the renderer you bring.
+
+### React case
You can define a renderer using [`@hono/react-renderer`](https://github.com/honojs/middleware/tree/main/packages/react-renderer). Install the modules first.
@@ -240,7 +331,7 @@ npm i @hono/react-renderer react react-dom hono
npm i -D @types/react @types/react-dom
```
-Next, define the Props that the renderer will receive in `global.d.ts`.
+Define the Props that the renderer will receive in `global.d.ts`.
```ts
// global.d.ts
@@ -253,7 +344,7 @@ declare module '@hono/react-renderer' {
}
```
-Write `_renderer.tsx`, which will load the `/app/client.ts` entry file for the client. It also loads the JavaScript file for the production according to the variable `import.meta.env.PROD`.
+The following is an example of `app/routes/renderer.tsx`.
```tsx
// app/routes/_renderer.tsx
@@ -282,9 +373,7 @@ export default reactRenderer(({ children, title }) => {
})
```
-### Client
-
-A client side entry file should be in `app/client.ts`. You can specify each option in `createClient()` for each UI library.
+The `app/client.ts` will be like this.
```ts
// app/client.ts
@@ -302,44 +391,7 @@ createClient({
})
```
-Function components placed in `app/islands/*` are also sent to the client side. For example, you can write interactive component such as the following counter:
-
-```tsx
-// app/islands/counter.tsx
-import { useState } from 'react'
-
-export default function Counter() {
- const [count, setCount] = useState(0)
- const increment = () => setCount(count + 1)
- return (
-
-
- Count: {count}
-
-
-
- )
-}
-```
-
-When you load the component in a route file, it is rendered as Server-Side rendering and JavaScript is also delivered to the client-side.
-
-```tsx
-// app/routes/index.tsx
-import { createRoute } from 'honox/factory'
-import Counter from '../islands/counter'
-
-export default createRoute((c) => {
- return c.render(
-
-
Hello
-
-
- )
-})
-```
-
-## Guide
+## Guides
### Using Middleware
@@ -408,13 +460,9 @@ export default jsxRenderer(({ children }) => {
{import.meta.env.PROD ? (
- <>
-
- >
+
) : (
- <>
-
- >
+
)}
{children}
@@ -423,6 +471,63 @@ export default jsxRenderer(({ children }) => {
})
```
+### MDX
+
+MDX can also be used. Here is the `vite.config.ts`.
+
+```ts
+import devServer from '@hono/vite-dev-server'
+import mdx from '@mdx-js/rollup'
+import honox from 'honox/vite'
+import remarkFrontmatter from 'remark-frontmatter'
+import remarkMdxFrontmatter from 'remark-mdx-frontmatter'
+import { defineConfig } from '../../node_modules/vite'
+
+const entry = './app/server.ts'
+
+export default defineConfig(() => {
+ return {
+ plugins: [
+ honox(),
+ devServer({ entry }),
+ mdx({
+ jsxImportSource: 'hono/jsx',
+ remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter],
+ }),
+ ],
+ }
+})
+```
+
+Blog site can be created.
+
+```tsx
+// app/routes/index.tsx
+import type { Meta } from '../types'
+
+export default function Top() {
+ const posts = import.meta.glob<{ frontmatter: Meta }>('./posts/*.mdx', {
+ eager: true,
+ })
+ return (
+