create-riebeckite 0.0.19 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +3 -3
  2. package/README_ja.md +1 -1
  3. package/dist/src/index.js +24 -24
  4. package/dist/src/scaffold/index.js +24 -24
  5. package/dist/src/scaffold/version.d.ts +1 -1
  6. package/dist/src/scaffold/wrangler-defaults.d.ts +1 -1
  7. package/package.json +2 -2
  8. package/templates/scaffold/base/app/global.d.ts +9 -3
  9. package/templates/scaffold/base/app/server.ts +2 -2
  10. package/templates/scaffold/base/vite.config.ts +3 -25
  11. package/templates/scaffold/presets/empty/app/routes/_404.tsx +18 -0
  12. package/templates/scaffold/presets/empty/app/routes/_renderer.tsx +1 -1
  13. package/templates/scaffold/presets/empty/app/routes/index.tsx +1 -1
  14. package/templates/scaffold/presets/empty/app/style.css +11 -0
  15. package/templates/scaffold/presets/minimal/app/routes/[slug{.+}].tsx +13 -32
  16. package/templates/scaffold/presets/minimal/app/routes/_404.tsx +18 -0
  17. package/templates/scaffold/presets/minimal/app/routes/_renderer.tsx +17 -53
  18. package/templates/scaffold/presets/minimal/app/routes/index.tsx +9 -19
  19. package/templates/scaffold/presets/minimal/app/style.css +13 -21
  20. package/templates/scaffold/presets/minimal/content/index.en.md +16 -6
  21. package/templates/scaffold/presets/showcase/app/components/site-header.tsx +10 -64
  22. package/templates/scaffold/presets/showcase/app/routes/[slug{.+}].tsx +15 -34
  23. package/templates/scaffold/presets/showcase/app/routes/_404.tsx +18 -0
  24. package/templates/scaffold/presets/showcase/app/routes/_renderer.tsx +31 -49
  25. package/templates/scaffold/presets/showcase/app/routes/index.tsx +19 -25
  26. package/templates/scaffold/presets/showcase/app/style.css +26 -42
  27. package/templates/scaffold/presets/showcase/content/Daily/2026-09-28.md +8 -0
  28. package/templates/scaffold/presets/showcase/content/Daily/2026-09-30.md +8 -0
  29. package/templates/scaffold/presets/showcase/content/Daily/2026-10-02.md +11 -0
  30. package/templates/scaffold/presets/showcase/content/index.de.md +16 -5
  31. package/templates/scaffold/presets/showcase/content/index.en.md +16 -5
  32. package/templates/scaffold/presets/showcase/content/index.es.md +16 -5
  33. package/templates/scaffold/presets/showcase/content/index.fr.md +16 -5
  34. package/templates/scaffold/presets/showcase/content/index.ja.md +16 -5
  35. package/templates/scaffold/presets/showcase/content/index.ko.md +16 -5
  36. package/templates/scaffold/presets/showcase/content/index.zh-CN.md +16 -5
  37. package/templates/scaffold/presets/starter/app/components/site-header.tsx +10 -64
  38. package/templates/scaffold/presets/starter/app/routes/[slug{.+}].tsx +15 -34
  39. package/templates/scaffold/presets/starter/app/routes/_404.tsx +18 -0
  40. package/templates/scaffold/presets/starter/app/routes/_renderer.tsx +31 -49
  41. package/templates/scaffold/presets/starter/app/routes/index.tsx +17 -25
  42. package/templates/scaffold/presets/starter/app/style.css +26 -42
  43. package/templates/scaffold/base/app/config.ts +0 -18
  44. package/templates/scaffold/base/app/constants/paths.ts +0 -10
  45. package/templates/scaffold/base/app/content.ts +0 -12
@@ -1,59 +1,23 @@
1
- import type { PluginHeadTag } from "@riebeckite/core";
1
+ import { RiebeckiteHead, ThemeRoot } from "@riebeckite/honox/ui";
2
2
  import { jsxRenderer } from "hono/jsx-renderer";
3
- import { Link, Script } from "honox/server";
4
- import { config } from "../config";
5
-
6
- function themeAttributes() {
7
- const { theme } = config;
8
-
9
- return {
10
- ...theme.attributes,
11
- "data-theme": theme.colorMode === "system" ? undefined : theme.colorMode,
12
- "data-theme-name": theme.name,
13
- "data-typography": theme.typography,
14
- "data-article-layout": theme.articleLayout,
15
- };
16
- }
3
+ import { config } from "virtual:riebeckite/config";
17
4
 
18
5
  // Riebeckite plugin client entries need the HonoX client bundle even without
19
6
  // an island component.
20
7
  export const __importing_islands = true;
21
8
 
22
- export default jsxRenderer(async ({ children }, c) => {
23
- const headTags: readonly PluginHeadTag[] = c.get("headTags") ?? [];
24
-
25
- return (
26
- <html
27
- lang={c.get("htmlLanguage") ?? config.site.locale}
28
- {...themeAttributes()}
29
- >
30
- <head>
31
- <meta charset="utf-8" />
32
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
33
- <title>{config.site.title}</title>
34
- <link rel="icon" href="/favicon.ico" />
35
- <Link href="/app/style.css" rel="stylesheet" />
36
- {headTags.map(renderHeadTag)}
37
- <Script src="/app/client.ts" async />
38
- </head>
39
- <body class="riebeckite-page rb-site">
40
- {children}
41
- </body>
42
- </html>
43
- );
44
- });
45
-
46
- function renderHeadTag(tag: PluginHeadTag, index: number) {
47
- const key = `${tag.tag}-${index}`;
48
- if (tag.tag === "meta") return <meta {...tag.attrs} key={key} />;
49
- if (tag.tag === "link") return <link {...tag.attrs} key={key} />;
50
- return (
51
- <script
52
- {...tag.attrs}
53
- key={key}
54
- dangerouslySetInnerHTML={
55
- tag.children ? { __html: tag.children } : undefined
56
- }
57
- />
58
- );
59
- }
9
+ export default jsxRenderer(({ children }, c) => (
10
+ <ThemeRoot
11
+ theme={config.theme}
12
+ lang={c.get("htmlLanguage") ?? config.site.locale}
13
+ >
14
+ <head>
15
+ <RiebeckiteHead
16
+ title={config.site.title}
17
+ headTags={c.get("headTags") ?? []}
18
+ colorModeScript={false}
19
+ />
20
+ </head>
21
+ <body class="riebeckite-page rb-site">{children}</body>
22
+ </ThemeRoot>
23
+ ));
@@ -1,29 +1,19 @@
1
- import { getEntryLanguage } from "@riebeckite/core";
1
+ import { resolveRiebeckiteHomeRequest } from "@riebeckite/honox/server";
2
+ import { PageBody } from "@riebeckite/honox/ui";
2
3
  import { createRoute } from "honox/factory";
3
4
  import { SiteArticle } from "../components/article";
4
- import { content } from "../content";
5
+ import { content } from "virtual:riebeckite/content";
5
6
 
6
7
  export default createRoute(async (c) => {
7
- const manifest = await content.getManifest();
8
- const indexEntry = manifest.bySlug.get("index");
9
- if (indexEntry && indexEntry.permalink !== "/") {
10
- return c.redirect(indexEntry.permalink, 308);
11
- }
8
+ const home = await resolveRiebeckiteHomeRequest(c, content);
12
9
 
13
- const post = await content.getProcessedContent("index");
14
- if (indexEntry?.publishing?.routable === false) {
15
- return c.notFound();
16
- }
10
+ if (home.kind === "response") return home.response;
17
11
 
18
- if (indexEntry) {
19
- c.set("htmlLanguage", getEntryLanguage(indexEntry));
20
- c.set("headTags", indexEntry.headTags ?? []);
12
+ if (home.kind === "page") {
13
+ return c.render(<PageBody html={home.page.body} />);
21
14
  }
22
15
 
23
16
  return c.render(
24
- <SiteArticle
25
- post={post}
26
- bodySlots={indexEntry?.bodySlots}
27
- />,
17
+ <SiteArticle post={home.post} bodySlots={home.entry.bodySlots} />,
28
18
  );
29
- });
19
+ });
@@ -1,3 +1,4 @@
1
+ @import "./.riebeckite/framework-styles.css";
1
2
  @import "./.riebeckite/plugin-styles.css";
2
3
  @import "./.riebeckite/theme-styles.css";
3
4
 
@@ -28,13 +29,6 @@ body {
28
29
  margin: 0 auto;
29
30
  }
30
31
 
31
- .rb-article-layout {
32
- display: grid;
33
- grid-template-columns: minmax(0, var(--rb-layout-article-max, 48rem));
34
- justify-content: center;
35
- column-gap: var(--rb-layout-gap, 2rem);
36
- }
37
-
38
32
  .rb-article-body,
39
33
  .site-article__footer {
40
34
  min-width: 0;
@@ -46,16 +40,6 @@ body {
46
40
  }
47
41
 
48
42
  @media (min-width: 88rem) {
49
- :is(:root, .rb-theme-root)[data-article-layout="article"] .rb-article-layout {
50
- grid-template-columns: minmax(0, var(--rb-layout-article-max, 48rem));
51
- position: relative;
52
- }
53
-
54
- :is(:root, .rb-theme-root)[data-article-layout="article"] .rb-article-body {
55
- grid-column: 1;
56
- grid-row: 1;
57
- }
58
-
59
43
  :is(:root, .rb-theme-root)[data-article-layout="article"] .site-article__footer {
60
44
  grid-column: 1;
61
45
  }
@@ -64,18 +48,26 @@ body {
64
48
  display: block;
65
49
  grid-column: 1;
66
50
  grid-row: 1;
67
- position: sticky;
68
- top: 4rem;
69
51
  align-self: start;
70
52
  width: var(--rb-layout-sidebar, 14rem);
71
- max-height: calc(100dvh - 8rem);
72
53
  margin-inline-start: calc(
73
54
  -1 * var(--rb-layout-sidebar, 14rem) -
74
55
  var(--rb-layout-gap, 2rem)
75
56
  );
76
- overflow: auto;
77
57
  padding-inline-end: 1rem;
78
58
  border-inline-end: 1px solid
79
59
  color-mix(in oklab, currentColor 18%, transparent);
80
60
  }
81
61
  }
62
+
63
+ .not-found {
64
+ width: min(100% - 2rem, var(--rb-layout-article-max, 48rem));
65
+ margin-block: auto;
66
+ padding-block: 2rem;
67
+ }
68
+
69
+ .not-found__status {
70
+ margin: 0;
71
+ color: var(--rb-color-accent);
72
+ font-weight: 700;
73
+ }
@@ -3,10 +3,20 @@ publish: true
3
3
  ---
4
4
 
5
5
  # {{title}}
6
- Welcome to your Riebeckite site.
7
- Every page of this starter is available in seven languages. Switch with the selector below the page title.
8
- ## What is Riebeckite?
9
- Riebeckite is an extensible, content-first framework that builds fast static sites from plain Markdown — the same notes you keep in Obsidian. The ecosystem includes 50+ plugins and six themes, and this site demos both.
6
+
7
+ Welcome to your Riebeckite site. This is the smallest useful preset: one page, one plugin, and the `minimal` theme.
8
+
9
+ ## How this site is built
10
+
11
+ - `app/routes/_renderer.tsx` wraps every page in the shared HTML shell.
12
+ - `app/routes/index.tsx` renders this page, and `app/routes/[slug{.+}].tsx` renders every other page.
13
+ - `app/components/article.tsx` lays out an article.
14
+ - `riebeckite.config.ts` registers the plugin and the theme.
15
+
10
16
  ## Edit this site
11
- Content lives in `content/` as plain Markdown. Add a file, give it `publish: true` in the frontmatter, and it appears in the built site.
12
- Localized pages use the `<base>.<lang>.md` convention next to the default file — for example `about.ja.md`. The l10n plugin serves them under `/lang/` paths and links them automatically.
17
+
18
+ Content lives in `content/` as plain Markdown. Change this file and the browser updates while you write. Add another `.md` file with `publish: true` in its frontmatter and it becomes a page.
19
+
20
+ ## Add a feature
21
+
22
+ Install a plugin package and register its factory in `riebeckite.config.ts`. The `starter` preset shows a practical plugin set, and `showcase` demonstrates the complete ecosystem.
@@ -1,13 +1,16 @@
1
+ import { SiteNav } from "@riebeckite/plugin-navigation";
1
2
  import type { NavigationItem } from "@riebeckite/plugin-navigation";
2
3
  import { ColorModeToggle } from "@riebeckite/plugin-color-mode";
3
- import { config } from "../config";
4
+ import { config } from "virtual:riebeckite/config";
4
5
 
5
6
  export function SiteHeader({
6
7
  path,
7
8
  items,
9
+ language,
8
10
  }: {
9
11
  path: string;
10
12
  items: readonly NavigationItem[];
13
+ language?: string;
11
14
  }) {
12
15
  const navigation = items.filter((item) => item.href !== "/");
13
16
 
@@ -25,10 +28,10 @@ export function SiteHeader({
25
28
  </a>
26
29
  {navigation.length > 0 ? (
27
30
  <>
28
- <SiteNavigation items={navigation} path={path} />
29
- <details class="site-navigation__mobile rb-nav__mobile">
31
+ <SiteNav items={navigation} path={path} language={language} />
32
+ <details class="rb-nav__mobile">
30
33
  <summary class="rb-nav__toggle">Menu</summary>
31
- <SiteNavigation items={navigation} path={path} />
34
+ <SiteNav items={navigation} path={path} language={language} />
32
35
  </details>
33
36
  </>
34
37
  ) : null}
@@ -40,74 +43,17 @@ export function SiteHeader({
40
43
  export function SiteFooter({
41
44
  path,
42
45
  items,
46
+ language,
43
47
  }: {
44
48
  path: string;
45
49
  items: readonly NavigationItem[];
50
+ language?: string;
46
51
  }) {
47
52
  if (items.length === 0) return null;
48
53
 
49
54
  return (
50
55
  <footer class="site-footer rb-site-footer">
51
- <SiteNavigation items={items} path={path} />
56
+ <SiteNav items={items} path={path} language={language} />
52
57
  </footer>
53
58
  );
54
59
  }
55
-
56
- function SiteNavigation({
57
- items,
58
- path,
59
- }: {
60
- items: readonly NavigationItem[];
61
- path: string;
62
- }) {
63
- return (
64
- <nav class="site-navigation rb-nav" aria-label="Site navigation">
65
- <NavigationItems items={items} path={path} />
66
- </nav>
67
- );
68
- }
69
-
70
- function NavigationItems({
71
- items,
72
- path,
73
- isChildList = false,
74
- }: {
75
- items: readonly NavigationItem[];
76
- path: string;
77
- isChildList?: boolean;
78
- }) {
79
- return (
80
- <ul class={isChildList ? "site-navigation__list rb-nav__list rb-nav__children" : "site-navigation__list rb-nav__list"}>
81
- {items.map((item) => {
82
- const active = item.href ? isActive(item.href, path) : false;
83
- return (
84
- <li class="site-navigation__item rb-nav__item">
85
- {item.href ? (
86
- <a
87
- href={item.href}
88
- class={active ? "site-navigation__link rb-nav__link rb-nav__link--active is-active" : "site-navigation__link rb-nav__link"}
89
- aria-current={active ? "page" : undefined}
90
- target={item.external ? "_blank" : undefined}
91
- rel={item.external ? "noreferrer" : undefined}
92
- >
93
- {item.label}
94
- </a>
95
- ) : (
96
- <span class="site-navigation__label rb-nav__label">{item.label}</span>
97
- )}
98
- {item.children && item.children.length > 0 ? (
99
- <NavigationItems items={item.children} path={path} isChildList />
100
- ) : null}
101
- </li>
102
- );
103
- })}
104
- </ul>
105
- );
106
- }
107
-
108
- function isActive(href: string, path: string): boolean {
109
- if (!href.startsWith("/")) return false;
110
- const target = href.replace(/\/+$/, "") || "/";
111
- const current = path.replace(/^\/[a-z]{2}(?:-[A-Z]{2})?(?=\/|$)/, "").replace(/\/+$/, "") || "/";
112
- return target === "/" ? current === target : current === target || current.startsWith(`${target}/`);
113
- }
@@ -1,52 +1,33 @@
1
- import { getEntryLanguage } from "@riebeckite/core";
2
1
  import {
3
2
  contentRouteSsgParams,
4
- pluginPageSsgParams,
5
- resolveRiebeckiteRoute,
3
+ resolveRiebeckiteContentRequest,
4
+ riebeckiteSsgParams,
6
5
  } from "@riebeckite/honox/server";
6
+ import { PageBody } from "@riebeckite/honox/ui";
7
7
  import { extractTableOfContents, TableOfContents } from "@riebeckite/plugin-toc";
8
8
  import { createRoute } from "honox/factory";
9
9
  import { SiteArticle } from "../components/article";
10
- import { content } from "../content";
10
+ import { content } from "virtual:riebeckite/content";
11
11
 
12
12
  export default createRoute(
13
- contentRouteSsgParams("/:slug{.+}", async () => {
14
- const manifest = await content.getManifest();
15
- const contentPaths = manifest.publicEntries
16
- .filter((entry) => entry.permalink !== "/")
17
- .map((entry) => ({ slug: entry.permalink.replace(/^\/+/, "") }));
18
- return [...contentPaths, ...(await pluginPageSsgParams(content))];
19
- }),
13
+ contentRouteSsgParams("/:slug{.+}", () => riebeckiteSsgParams(content)),
20
14
  async (c) => {
21
- const requestedSlug = c.req.param("slug");
22
- if (!requestedSlug) return c.notFound();
23
- if (/\.[a-zA-Z0-9]+$/.test(requestedSlug)) return c.notFound();
15
+ const resolved = await resolveRiebeckiteContentRequest(c, content);
24
16
 
25
- const route = await resolveRiebeckiteRoute(content, c.req.path);
26
- if (!route) return c.notFound();
27
- if (route.kind === "redirect")
28
- return c.redirect(route.location, route.status);
29
- if (route.kind === "page") {
30
- c.set("headTags", route.page.headTags ?? []);
31
- c.set("htmlLanguage", route.page.language);
32
- return c.render(
33
- <div dangerouslySetInnerHTML={{ __html: route.page.body }} />,
34
- );
35
- }
36
-
37
- const post = await content.getProcessedContent(route.entry.slug);
17
+ if (resolved.kind === "response") return resolved.response;
38
18
 
39
- const tableOfContents = extractTableOfContents(post.html ?? "");
19
+ if (resolved.kind === "page") {
20
+ return c.render(<PageBody html={resolved.page.body} />);
21
+ }
40
22
 
41
- c.set("htmlLanguage", getEntryLanguage(route.entry));
42
- c.set("headTags", route.entry.headTags ?? []);
23
+ const tableOfContents = extractTableOfContents(resolved.post.html ?? "");
43
24
 
44
25
  return c.render(
45
26
  <SiteArticle
46
- post={post}
47
- bodySlots={route.entry.bodySlots}
48
- asideContent={<TableOfContents className="table-of-contents--desktop" items={tableOfContents} />}
27
+ post={resolved.post}
28
+ bodySlots={resolved.entry.bodySlots}
29
+ asideContent={<TableOfContents className="rr-table-of-contents--desktop" items={tableOfContents} />}
49
30
  />,
50
31
  );
51
32
  },
52
- );
33
+ );
@@ -0,0 +1,18 @@
1
+ import type { NotFoundHandler } from "hono";
2
+
3
+ const handler: NotFoundHandler = (c) => {
4
+ c.status(404);
5
+
6
+ return c.render(
7
+ <div class="not-found">
8
+ <p class="not-found__status">404</p>
9
+ <h1>Page not found</h1>
10
+ <p>The page you requested does not exist or is not available.</p>
11
+ <p>
12
+ <a href="/">Back to home</a>
13
+ </p>
14
+ </div>,
15
+ );
16
+ };
17
+
18
+ export default handler;
@@ -1,69 +1,51 @@
1
- import type { PluginHeadTag } from "@riebeckite/core";
1
+ import { RiebeckiteHead, ThemeRoot } from "@riebeckite/honox/ui";
2
2
  import { jsxRenderer } from "hono/jsx-renderer";
3
- import { Link, Script } from "honox/server";
4
- import { ColorModeScript } from "@riebeckite/plugin-color-mode";
5
- import { SearchBar } from "@riebeckite/plugin-search";
6
3
  import { resolveSiteNavigation } from "@riebeckite/plugin-navigation";
4
+ import { SearchBar } from "@riebeckite/plugin-search";
7
5
  import { SiteFooter, SiteHeader } from "../components/site-header";
8
- import { content } from "../content";
9
- import { config } from "../config";
10
-
11
- function themeAttributes() {
12
- const { theme } = config;
13
-
14
- return {
15
- ...theme.attributes,
16
- "data-theme": theme.colorMode === "system" ? undefined : theme.colorMode,
17
- "data-theme-name": theme.name,
18
- "data-typography": theme.typography,
19
- "data-article-layout": theme.articleLayout,
20
- };
21
- }
6
+ import { content } from "virtual:riebeckite/content";
7
+ import { config } from "virtual:riebeckite/config";
22
8
 
23
9
  // Riebeckite plugin client entries need the HonoX client bundle even without
24
10
  // an island component.
25
11
  export const __importing_islands = true;
26
12
 
27
13
  export default jsxRenderer(async ({ children }, c) => {
28
- const headTags: readonly PluginHeadTag[] = c.get("headTags") ?? [];
29
- const navigation = resolveSiteNavigation(config, await content.getManifest(), c.get("htmlLanguage")) ?? { primary: [], secondary: [] };
14
+ const navigation =
15
+ resolveSiteNavigation(
16
+ config,
17
+ await content.getManifest(),
18
+ c.get("htmlLanguage"),
19
+ ) ?? { primary: [], secondary: [] };
30
20
 
31
21
  return (
32
- <html
22
+ <ThemeRoot
23
+ theme={config.theme}
33
24
  lang={c.get("htmlLanguage") ?? config.site.locale}
34
- {...themeAttributes()}
35
25
  >
36
26
  <head>
37
- <meta charset="utf-8" />
38
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
39
- <title>{config.site.title}</title>
40
- <link rel="icon" href="/favicon.ico" />
41
- <ColorModeScript />
42
- <Link href="/app/style.css" rel="stylesheet" />
43
- {headTags.map(renderHeadTag)}
44
- <Script src="/app/client.ts" async />
27
+ <RiebeckiteHead
28
+ title={config.site.title}
29
+ headTags={c.get("headTags") ?? []}
30
+ />
45
31
  </head>
46
32
  <body class="riebeckite-page rb-site">
47
- <SiteHeader path={c.req.path} items={navigation.primary} />
33
+ <a class="rb-skip-link" href="#main-content">Skip to main content</a>
34
+ <SiteHeader
35
+ path={c.req.path}
36
+ items={navigation.primary}
37
+ language={c.get("htmlLanguage")}
38
+ />
48
39
  <SearchBar />
49
- {children}
50
- <SiteFooter path={c.req.path} items={navigation.secondary} />
40
+ <main id="main-content" tabindex="-1" class="riebeckite-main">
41
+ {children}
42
+ </main>
43
+ <SiteFooter
44
+ path={c.req.path}
45
+ items={navigation.secondary}
46
+ language={c.get("htmlLanguage")}
47
+ />
51
48
  </body>
52
- </html>
49
+ </ThemeRoot>
53
50
  );
54
51
  });
55
-
56
- function renderHeadTag(tag: PluginHeadTag, index: number) {
57
- const key = `${tag.tag}-${index}`;
58
- if (tag.tag === "meta") return <meta {...tag.attrs} key={key} />;
59
- if (tag.tag === "link") return <link {...tag.attrs} key={key} />;
60
- return (
61
- <script
62
- {...tag.attrs}
63
- key={key}
64
- dangerouslySetInnerHTML={
65
- tag.children ? { __html: tag.children } : undefined
66
- }
67
- />
68
- );
69
- }
@@ -1,39 +1,33 @@
1
- import { getEntryLanguage } from "@riebeckite/core";
2
- import { createRoute } from "honox/factory";
1
+ import { resolveRiebeckiteHomeRequest } from "@riebeckite/honox/server";
2
+ import { PageBody } from "@riebeckite/honox/ui";
3
3
  import { DailyNotes, getDailyNotes } from "@riebeckite/plugin-daily-notes";
4
- import { RecentPosts, getRecentPosts } from "@riebeckite/plugin-recent-posts";
4
+ import { getRecentPosts, RecentPosts } from "@riebeckite/plugin-recent-posts";
5
5
  import { extractTableOfContents, TableOfContents } from "@riebeckite/plugin-toc";
6
+ import { createRoute } from "honox/factory";
6
7
  import { SiteArticle } from "../components/article";
7
- import { config } from "../config";
8
- import { content } from "../content";
8
+ import { config } from "virtual:riebeckite/config";
9
+ import { content } from "virtual:riebeckite/content";
9
10
 
10
11
  export default createRoute(async (c) => {
11
- const manifest = await content.getManifest();
12
- const indexEntry = manifest.bySlug.get("index");
13
- if (indexEntry && indexEntry.permalink !== "/") {
14
- return c.redirect(indexEntry.permalink, 308);
15
- }
12
+ const home = await resolveRiebeckiteHomeRequest(c, content);
16
13
 
17
- const post = await content.getProcessedContent("index");
18
- if (indexEntry?.publishing?.routable === false) {
19
- return c.notFound();
14
+ if (home.kind === "response") return home.response;
15
+
16
+ if (home.kind === "page") {
17
+ return c.render(<PageBody html={home.page.body} />);
20
18
  }
21
19
 
22
- const recentPosts = await getRecentPosts({ posts: manifest.discoverableEntries, config, getProcessedContent: (slug) => content.getProcessedContent(slug), resolveTitle: (slug, title) => typeof title === "string" && title.trim() ? title : slug.split("/").at(-1) ?? slug });
20
+ const manifest = await content.getManifest();
21
+ const recentPosts = getRecentPosts({ manifest });
23
22
  const dailyNotes = getDailyNotes({ manifest, config });
24
- const tableOfContents = extractTableOfContents(post.html ?? "");
25
-
26
- if (indexEntry) {
27
- c.set("htmlLanguage", getEntryLanguage(indexEntry));
28
- c.set("headTags", indexEntry.headTags ?? []);
29
- }
23
+ const tableOfContents = extractTableOfContents(home.post.html ?? "");
30
24
 
31
25
  return c.render(
32
26
  <SiteArticle
33
- post={post}
34
- bodySlots={indexEntry?.bodySlots}
35
- asideContent={<TableOfContents className="table-of-contents--desktop" items={tableOfContents} />}
36
- afterContent={<><RecentPosts posts={recentPosts} /><DailyNotes notes={dailyNotes} /></>}
27
+ post={home.post}
28
+ bodySlots={home.entry.bodySlots}
29
+ asideContent={<TableOfContents className="rr-table-of-contents--desktop" items={tableOfContents} />}
30
+ afterContent={<><RecentPosts posts={recentPosts} /><DailyNotes notes={dailyNotes} /></>}
37
31
  />,
38
32
  );
39
- });
33
+ });