npm package: @gyoll/adapter-solid-router
Description: Solid Router adapter for Gyoll file-based routing
Latest version: 0.9.4

# @gyoll/adapter-solid-router

Solid Router adapter for Gyoll file-based routing.

## Installation

```bash
pnpm add @gyoll/adapter-solid-router @gyoll/runtime
pnpm add solid-js @solidjs/router  # peer dependencies
```

## Usage

```javascript
import { render } from "solid-js/web";
import { initFileRoutes } from "@gyoll/runtime";
import { solidRouterAdapter } from "@gyoll/adapter-solid-router";
import { routes } from "./gyoll-manifest.js";

const RouterComponent = await initFileRoutes({
  routes,
  adapter: solidRouterAdapter,
});

render(() => <RouterComponent />, document.getElementById("root"));
```

## File-Based Routing Conventions

### Supported Files

- **`page.jsx`** - Route component (lazy-loaded automatically)
- **`layout.jsx`** - Wraps child routes
- **Route groups** - `(group)` directories don't affect URLs
- **Dynamic segments** - `[id]` becomes `:id`
- **Catch-all routes** - `[...slug]` becomes `*`

### Example Structure

```
src/routes/
├── page.jsx              → /
├── about/
│   └── page.jsx          → /about
├── blog/
│   ├── layout.jsx        → wraps all /blog/* routes
│   ├── page.jsx          → /blog
│   └── [slug]/
│       └── page.jsx      → /blog/:slug
└── (auth)/
    ├── login/
    │   └── page.jsx      → /login (group doesn't affect URL)
    └── register/
        └── page.jsx      → /register
```

## Framework-Specific Behavior

### Error Handling

Solid Router does **not** support error boundaries at the route configuration level. Use Solid's `<ErrorBoundary>` component in your layouts or pages:

```jsx
// layout.jsx
import { ErrorBoundary } from "solid-js";

export default function Layout(props) {
  return (
    <ErrorBoundary fallback={(err) => <div>Error: {err.message}</div>}>
      {props.children}
    </ErrorBoundary>
  );
}
```

### Loading States

Solid Router automatically integrates with `<Suspense>` boundaries. All components are lazy-loaded, so wrap your layout with Suspense:

```jsx
// layout.jsx
import { Suspense } from "solid-js";

export default function Layout(props) {
  return <Suspense fallback={<div>Loading...</div>}>{props.children}</Suspense>;
}
```

### Data Loading

Export a `routeData` or `loader` function from your page components:

```jsx
// page.jsx
export async function routeData() {
  const response = await fetch("/api/data");
  return response.json();
}

export default function Page(props) {
  const data = props.data; // Access loaded data
  return <div>{data.title}</div>;
}
```

## Unsupported Features

Due to Solid Router's design, the following Gyoll conventions are **not supported**:

- ❌ `error.jsx` - Use `<ErrorBoundary>` components instead
- ❌ `loading.jsx` - Use `<Suspense>` components instead

These are handled at the component level in Solid, not the route configuration level.

## API

### `solidRouterAdapter`

```javascript
{
  createRouter(routes, options), // Returns Router component
    transformRoutes(routes); // Transforms manifest to Solid format
}
```

### Router Options

Pass options to Solid Router's `<Router>`:

```javascript
const RouterComponent = await initFileRoutes({
  routes,
  adapter: solidRouterAdapter,
  routerOptions: {
    root: App, // Root component
    base: "/app", // Base path
    // ... other Router props
  },
});
```

## Layout Wrapping

Layouts automatically wrap their child routes:

```jsx
// routes/dashboard/layout.jsx
export default function DashboardLayout(props) {
  return (
    <div class="dashboard">
      <nav>Dashboard Nav</nav>
      {props.children}
    </div>
  );
}

// routes/dashboard/page.jsx
export default function Dashboard() {
  return <h1>Dashboard Home</h1>;
}

// Result: Dashboard page wrapped in DashboardLayout
```