Loading...
Loading...
Learn how to host PocketBase and an Astro SSR application on the same server, using PocketBase's Go integration and a reverse proxy to delegate requests to Astro for dynamic web content.
npx skill4agent add rodydavis/skills how-to-run-astro-ssr-and-pocketbase-on-the-same-servermkdir pocketbase_astro_ssr
cd pocketbase_astro_ssr
mkdir server
mkdir wwwserverwwwserver/main.gopackage main
import (
"log"
"net/http/httputil"
"net/url"
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/core"
)
func main() {
app := pocketbase.New()
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
proxy := httputil.NewSingleHostReverseProxy(&url.URL{
Scheme: "http",
Host: "localhost:4321",
})
e.Router.Any("/*", echo.WrapHandler(proxy))
e.Router.Any("/", echo.WrapHandler(proxy))
return nil
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}go mod init server
go mod tidygo run main.go serve2023/11/09 10:28:52 Server started at http://127.0.0.1:8090
├─ REST API: http://127.0.0.1:8090/api/
└─ Admin UI: http://127.0.0.1:8090/_/itemsThis is just for example purposes and on a production app you will rely on auth for ACLs
wwwnpm create astro@latestnpm i -D @astrojs/node
npm i pocketbasewww/astro.config.mjsimport { defineConfig } from "astro/config";
import nodejs from "@astrojs/node";
// https://astro.build/config
export default defineConfig({
adapter: nodejs({
mode: "standalone",
}),
output: "server",
});www/src/layouts/Root.astro---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<slot />
</body>
</html>/www/src/pages/index.astro---
import Root from "../layouts/Root.astro";
import PocketBase from "pocketbase";
const pb = new PocketBase("http://127.0.0.1:8090");
const items = pb.collection("items");
const records = await items.getFullList();
---
<Root title="Items">
<h1>Items</h1>
<ul>
{
records.map((record) => (
<li>
<a href={`/items/${record.id}`}>{record.title}</a>
</li>
))
}
</ul>
</Root>itemswww/src/pages/[...slug].astro---
import Root from "../layouts/Root.astro";
import PocketBase from "pocketbase";
const slug = Astro.params.slug!;
const id = slug.split("/").pop()!;
const pb = new PocketBase("http://127.0.0.1:8090");
const items = pb.collection("items");
const records = await items.getList(1, 1, {
filter: `id = '${id}'`,
});
if (records.items.length === 0) {
return new Response("Not found", { status: 404 });
}
const {title} = records.items[0];
---
<Root {title}>
<a href="/">Back</a>
<h1>{title}</h1>
</Root>404npm run dev> dev
> astro dev
🚀 astro v3.4.4 started in 67ms
┃ Local http://localhost:4321/
┃ Network use --host to exposehttp://127.0.0.1:8090