@publish.os/nextjs 0.0.1-alpha.90 → 0.0.1-alpha.91

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 (223) hide show
  1. package/compiler-assets/nextjs/defaults/group/layout.tsx +1 -5
  2. package/compiler-assets/nextjs/defaults/group/page.tsx +31 -22
  3. package/compiler-assets/nextjs/defaults/project/next.config.mjs +19 -10
  4. package/compiler-assets/nextjs/defaults/project/tsconfig.json.template +10 -0
  5. package/compiler-assets/nextjs/defaults/root/css/components/code-block.css +18 -0
  6. package/compiler-assets/nextjs/shims/document.tsx +38 -0
  7. package/compiler-assets/nextjs/shims/generated-leaf-page.tsx +2 -0
  8. package/compiler-assets/nextjs/shims/global-layout.tsx +8 -42
  9. package/compiler-assets/nextjs/shims/global-not-found.tsx +69 -0
  10. package/compiler-assets/nextjs/shims/markdown-route.ts +2 -0
  11. package/compiler-assets/nextjs/shims/metadata-icons.tsx +39 -0
  12. package/compiler-assets/nextjs/shims/not-found-content.tsx +53 -0
  13. package/compiler-assets/nextjs/shims/not-found-navigation.tsx +60 -0
  14. package/compiler-assets/nextjs/shims/proxy.ts +126 -60
  15. package/compiler-assets/nextjs/shims/site-fenced-code-block.tsx +2 -6
  16. package/compiler-assets/nextjs/shims/site-mdx-components.tsx +28 -16
  17. package/compiler-assets/nextjs/shims/site-mdx.tsx +6 -1
  18. package/dist/{build-operation-2JAYBSKF.js → build-operation-5QMLXF7N.js} +29 -23
  19. package/dist/{button-c3WGnxIj.d.ts → button-BdCScEKi.d.ts} +3 -3
  20. package/dist/capture-local-source-WGGDIUU2.js +258 -0
  21. package/dist/chunk-22RSSUNV.js +13 -0
  22. package/dist/{chunk-WKTEO6RS.js → chunk-4BC2L2KA.js} +46 -12
  23. package/dist/{chunk-WDY4IK6Z.js → chunk-5J3YUNRY.js} +3 -10
  24. package/dist/chunk-5KAD7W53.js +248 -0
  25. package/dist/{chunk-DWA3ZRGW.js → chunk-6C65KV7O.js} +2 -2
  26. package/dist/{chunk-GGKFQ3MA.js → chunk-6D2E6UMD.js} +144 -70
  27. package/dist/{chunk-7OGTPSKI.js → chunk-7NY22B5U.js} +8 -3
  28. package/dist/chunk-EFO6AWXN.js +19 -0
  29. package/dist/{chunk-726GV2NF.js → chunk-F3AGNDF4.js} +100 -67
  30. package/dist/chunk-GBPLER5H.js +426 -0
  31. package/dist/chunk-IL4RJOKI.js +186 -0
  32. package/dist/{chunk-DLDFHU7Y.js → chunk-NNBJZPFM.js} +4 -2
  33. package/dist/{chunk-VO2I7MTM.js → chunk-ORIUWJBQ.js} +8 -6
  34. package/dist/{chunk-H6XILMZX.js → chunk-OXOFRXEI.js} +1806 -831
  35. package/dist/chunk-UYGCOWRF.js +1709 -0
  36. package/dist/{chunk-YLTOLYWM.js → chunk-WL75GQ5M.js} +6 -18
  37. package/dist/compiler.d.ts +15 -2
  38. package/dist/compiler.js +90 -21
  39. package/dist/components/blocks/agent-actions.d.ts +81 -0
  40. package/dist/components/blocks/agent-actions.js +594 -0
  41. package/dist/components/blocks/toc.d.ts +43 -0
  42. package/dist/components/blocks/toc.js +136 -0
  43. package/dist/components/ui/button.d.ts +5 -0
  44. package/dist/components/ui/button.js +94 -0
  45. package/dist/compose-CVBJRAF6.js +16 -0
  46. package/dist/config/createNextConfig.js +17 -3
  47. package/dist/{dev-operation-TZDVJCN7.js → dev-operation-OSHHWRWK.js} +121 -81
  48. package/dist/{framework-selection-X4U6Y6QC.js → framework-selection-ZVO323PK.js} +3 -2
  49. package/dist/ide-support-CU6Z5PVR.js +16 -0
  50. package/dist/index.d.ts +40 -1
  51. package/dist/jsx-dev-runtime.d.ts +6 -0
  52. package/dist/jsx-dev-runtime.js +100 -0
  53. package/dist/jsx-runtime.d.ts +7 -0
  54. package/dist/jsx-runtime.js +97 -0
  55. package/dist/kernel/components/blocks/AgentActions.d.ts +35 -6
  56. package/dist/kernel/components/blocks/AgentActions.js +383 -142
  57. package/dist/kernel/components/blocks/agent-actions.d.ts +5 -0
  58. package/dist/kernel/components/blocks/agent-actions.js +594 -0
  59. package/dist/kernel/components/blocks/animated-icon-swap.js +1 -1
  60. package/dist/kernel/components/blocks/color-palette.js +4 -4
  61. package/dist/kernel/components/blocks/logo-block.js +1 -1
  62. package/dist/kernel/components/blocks/nav-breadcrumb.js +2 -2
  63. package/dist/kernel/components/blocks/navbar.js +17 -17
  64. package/dist/kernel/components/blocks/navigation-progress.js +2 -2
  65. package/dist/kernel/components/blocks/next-prev.js +1 -1
  66. package/dist/kernel/components/blocks/page-list.js +2 -2
  67. package/dist/kernel/components/blocks/search.d.ts +1 -1
  68. package/dist/kernel/components/blocks/search.js +16 -17
  69. package/dist/kernel/components/blocks/sidebar-node.js +1 -1
  70. package/dist/kernel/components/blocks/sidebar.js +7 -4
  71. package/dist/kernel/components/blocks/theme-toggle.d.ts +1 -1
  72. package/dist/kernel/components/blocks/theme-toggle.js +5 -5
  73. package/dist/kernel/components/blocks/toc-client.d.ts +40 -0
  74. package/dist/kernel/components/blocks/toc-client.js +495 -0
  75. package/dist/kernel/components/blocks/toc.d.ts +19 -1
  76. package/dist/kernel/components/blocks/toc.js +121 -179
  77. package/dist/kernel/components/mdx/components/blockquote.js +1 -1
  78. package/dist/kernel/components/mdx/components/callout.js +1 -1
  79. package/dist/kernel/components/mdx/components/code-block.js +2 -2
  80. package/dist/kernel/components/mdx/components/copy-code-button.js +5 -4
  81. package/dist/kernel/components/mdx/components/figure-caption.d.ts +1 -1
  82. package/dist/kernel/components/mdx/components/figure-caption.js +3 -2
  83. package/dist/kernel/components/mdx/components/figure.d.ts +6 -2
  84. package/dist/kernel/components/mdx/components/figure.js +23 -13
  85. package/dist/kernel/components/mdx/components/footnotes.js +1 -1
  86. package/dist/kernel/components/mdx/components/heading-copy-link.js +1 -1
  87. package/dist/kernel/components/mdx/components/heading.js +6 -3
  88. package/dist/kernel/components/mdx/components/hr.js +2 -2
  89. package/dist/kernel/components/mdx/components/image-zoom.js +1 -1
  90. package/dist/kernel/components/mdx/components/image.d.ts +1 -1
  91. package/dist/kernel/components/mdx/components/image.js +21 -16
  92. package/dist/kernel/components/mdx/components/inline-code.js +1 -1
  93. package/dist/kernel/components/mdx/components/kbd.js +2 -2
  94. package/dist/kernel/components/mdx/components/link.d.ts +3 -3
  95. package/dist/kernel/components/mdx/components/link.js +2 -2
  96. package/dist/kernel/components/mdx/components/paragraph.js +1 -1
  97. package/dist/kernel/components/mdx/components/strikethrough.js +1 -1
  98. package/dist/kernel/components/mdx/components/table.js +2 -2
  99. package/dist/kernel/components/mdx/components/task-list.js +1 -1
  100. package/dist/kernel/components/mdx/components/video-player.d.ts +6 -2
  101. package/dist/kernel/components/mdx/components/video-player.js +6 -2
  102. package/dist/kernel/components/mdx/components/video.d.ts +5 -3
  103. package/dist/kernel/components/mdx/components/video.js +7 -5
  104. package/dist/kernel/components/mdx/error-boundary.d.ts +1 -1
  105. package/dist/kernel/components/mdx/error-boundary.js +2 -2
  106. package/dist/kernel/components/mdx/error-fallback.js +1 -1
  107. package/dist/kernel/components/mdx/mdx.d.ts +20 -10
  108. package/dist/kernel/components/mdx/mdx.js +231 -34
  109. package/dist/kernel/components/mdx/rehype-heading-ids.d.ts +1 -0
  110. package/dist/kernel/components/mdx/rehype-heading-ids.js +5 -3
  111. package/dist/kernel/components/mdx/types.d.ts +1 -1
  112. package/dist/kernel/components/next-image.d.ts +12 -0
  113. package/dist/kernel/components/next-image.js +61 -0
  114. package/dist/kernel/components/ui/accordion.js +1 -1
  115. package/dist/kernel/components/ui/breadcrumb-trail.d.ts +2 -2
  116. package/dist/kernel/components/ui/breadcrumb-trail.js +2 -2
  117. package/dist/kernel/components/ui/breadcrumb.d.ts +1 -1
  118. package/dist/kernel/components/ui/breadcrumb.js +4 -4
  119. package/dist/kernel/components/ui/button-group.d.ts +1 -1
  120. package/dist/kernel/components/ui/button-group.js +3 -3
  121. package/dist/kernel/components/ui/button.d.ts +56 -4
  122. package/dist/kernel/components/ui/button.js +43 -39
  123. package/dist/kernel/components/ui/card.js +1 -1
  124. package/dist/kernel/components/ui/dialog.js +1 -1
  125. package/dist/kernel/components/ui/drawer.js +1 -1
  126. package/dist/kernel/components/ui/input.d.ts +2 -2
  127. package/dist/kernel/components/ui/input.js +1 -1
  128. package/dist/kernel/components/ui/kbd.d.ts +1 -1
  129. package/dist/kernel/components/ui/kbd.js +1 -1
  130. package/dist/kernel/components/ui/link.d.ts +8 -2
  131. package/dist/kernel/components/ui/link.js +2 -2
  132. package/dist/kernel/components/ui/menu.js +1 -1
  133. package/dist/kernel/components/ui/mod-key.js +2 -2
  134. package/dist/kernel/components/ui/navigation-menu.js +1 -1
  135. package/dist/kernel/components/ui/popover.js +1 -1
  136. package/dist/kernel/components/ui/progress.js +1 -1
  137. package/dist/kernel/components/ui/scroll-area.d.ts +8 -8
  138. package/dist/kernel/components/ui/scroll-area.js +1 -1
  139. package/dist/kernel/components/ui/select.js +1 -1
  140. package/dist/kernel/components/ui/separator.js +1 -1
  141. package/dist/kernel/components/ui/table.js +1 -1
  142. package/dist/kernel/components/ui/tabs.js +1 -1
  143. package/dist/kernel/components/ui/tag.js +1 -1
  144. package/dist/kernel/components/ui/text.d.ts +1 -1
  145. package/dist/kernel/components/ui/text.js +1 -1
  146. package/dist/kernel/components/ui/toast.js +1 -1
  147. package/dist/kernel/components/ui/tooltip.js +1 -1
  148. package/dist/kernel/defaults.registry.d.ts +2 -15
  149. package/dist/kernel/defaults.registry.js +2 -17
  150. package/dist/kernel/routes/agent/markdown.d.ts +3 -0
  151. package/dist/kernel/routes/agent/markdown.js +219 -48
  152. package/dist/kernel/routes/layouts/group.d.ts +1 -1
  153. package/dist/kernel/routes/layouts/group.js +5 -7
  154. package/dist/kernel/routes/metadata/feed.d.ts +1 -1
  155. package/dist/kernel/routes/metadata/feed.js +109 -83
  156. package/dist/kernel/routes/metadata/llms.d.ts +11 -3
  157. package/dist/kernel/routes/metadata/llms.js +154 -57
  158. package/dist/kernel/routes/metadata/og-image.js +1 -1
  159. package/dist/kernel/routes/metadata/robots.d.ts +1 -1
  160. package/dist/kernel/routes/metadata/sitemap.d.ts +22 -3
  161. package/dist/kernel/routes/metadata/sitemap.js +183 -43
  162. package/dist/kernel/routes/not-found.d.ts +34 -0
  163. package/dist/kernel/routes/not-found.js +213 -0
  164. package/dist/kernel/routes/pages/group.d.ts +2 -2
  165. package/dist/kernel/routes/pages/group.js +1 -1
  166. package/dist/kernel/routes/pages/leaf.d.ts +30 -3
  167. package/dist/kernel/routes/pages/leaf.js +5 -4
  168. package/dist/kernel/routes/pages/root.d.ts +2 -2
  169. package/dist/kernel/routes/pages/root.js +1 -1
  170. package/dist/keyboard-shortcuts.js +1 -1
  171. package/dist/route-metadata-og-image-BeKKFHg7.d.ts +58 -0
  172. package/dist/search.js +7 -9
  173. package/dist/theme-scope.js +1 -1
  174. package/dist/{types-BzkZty3r.d.ts → types-J2w_puPF.d.ts} +1 -20
  175. package/dist/types-sM2g9nW0.d.ts +12 -0
  176. package/dist/types.d.ts +1 -0
  177. package/dist/utils/heading-ids.js +30 -11
  178. package/dist/utils/toc-selection.d.ts +7 -0
  179. package/dist/utils/toc-selection.js +14 -0
  180. package/dist/validate-local-source-SV44DBQT.js +16 -0
  181. package/dist/validate-publish-os-source-NZJF3TB2.js +14 -0
  182. package/init/seed/minimal/publish.os/assets/blog/hello-world.svg +13 -0
  183. package/init/seed/minimal/publish.os/assets/favicon.dark.svg +13 -0
  184. package/init/seed/minimal/publish.os/assets/favicon.svg +13 -0
  185. package/init/seed/minimal/publish.os/blog/content/hello-world.mdx +48 -0
  186. package/init/seed/minimal/publish.os/blog/content/series-a.mdx +11 -0
  187. package/init/seed/minimal/publish.os/blog/index.tsx +82 -0
  188. package/init/seed/minimal/publish.os/blog/layout.tsx +13 -0
  189. package/init/seed/minimal/publish.os/blog/page.tsx +76 -0
  190. package/init/seed/minimal/publish.os/components/blog/copy-link.tsx +64 -0
  191. package/init/seed/minimal/publish.os/docs/content/get-started.mdx +2 -3
  192. package/init/seed/minimal/publish.os/docs/content/groups.mdx +5 -6
  193. package/init/seed/minimal/publish.os/publish.os.config.json +6 -2
  194. package/init/seed/minimal/publish.os/theme.css +3 -3
  195. package/init/seed/minimal/seed.json +11 -4
  196. package/init/seed/scratch/publish.os/docs/content/get-started.mdx +1 -1
  197. package/init/seed/scratch/publish.os/publish.os.config.json +1 -1
  198. package/package.json +45 -20
  199. package/release/app/phosphor/package.json +3 -3
  200. package/release/app/phosphor/pnpm-lock.yaml.template +88 -75
  201. package/release/compiler/package.json +5 -3
  202. package/release/compiler/pnpm-lock.yaml.template +118 -74
  203. package/release/release.json +6 -6
  204. package/dist/button-CtzUJB8u.d.ts +0 -11
  205. package/dist/chunk-535TM4A5.js +0 -1455
  206. package/dist/chunk-B2V22WRT.js +0 -297
  207. package/dist/chunk-NECL5IBJ.js +0 -318
  208. package/dist/chunk-SVYGXXYR.js +0 -36
  209. package/dist/chunk-UF6ATARM.js +0 -1100
  210. package/dist/compose-NN23UJGC.js +0 -13
  211. package/dist/ide-support-ZNW7ODFY.js +0 -15
  212. package/dist/kernel/components/blocks/design-system-preview.d.ts +0 -61
  213. package/dist/kernel/components/blocks/design-system-preview.js +0 -667
  214. package/dist/kernel/components/blocks/link-playground.d.ts +0 -5
  215. package/dist/kernel/components/blocks/link-playground.js +0 -744
  216. package/dist/kernel/components/blocks/navigation-progress-playground.d.ts +0 -5
  217. package/dist/kernel/components/blocks/navigation-progress-playground.js +0 -629
  218. package/dist/kernel/components/ui/theme-toggle.d.ts +0 -24
  219. package/dist/kernel/components/ui/theme-toggle.js +0 -53
  220. package/dist/validate-local-source-XRL2Y7XE.js +0 -14
  221. package/dist/validate-publish-os-source-DAPZ4QGE.js +0 -12
  222. package/init/seed/minimal/publish.os/assets/favicon/favicon.dark.png +0 -0
  223. package/init/seed/minimal/publish.os/assets/favicon/favicon.png +0 -0
@@ -0,0 +1,58 @@
1
+ type OgImageEntryLike = {
2
+ key: string;
3
+ routePath: string;
4
+ title: string;
5
+ description?: string;
6
+ source: "asset" | "generated" | "remote";
7
+ url: string;
8
+ width: number;
9
+ height: number;
10
+ alt: string;
11
+ group?: string;
12
+ logo?: {
13
+ dataUri?: string;
14
+ height?: number;
15
+ kind: "logo" | "mark" | "wordmark";
16
+ url: string;
17
+ width?: number;
18
+ };
19
+ siteName?: string;
20
+ siteUrl?: string;
21
+ label?: string;
22
+ background?: string;
23
+ textPrimary?: string;
24
+ textSecondary?: string;
25
+ accent?: string;
26
+ stroke?: string;
27
+ theme?: "light" | "dark";
28
+ fonts?: {
29
+ main: OgFontRoleLike;
30
+ mono: OgFontRoleLike;
31
+ };
32
+ emoji?: Readonly<Record<string, string>>;
33
+ fallbackGlyphs?: Partial<Record<"main" | "mono", Readonly<Record<string, string>>>>;
34
+ fallbackFonts?: ReadonlyArray<{
35
+ family: string;
36
+ data: string;
37
+ style: "normal" | "italic";
38
+ weight: number;
39
+ }>;
40
+ };
41
+ type OgManifestLike = {
42
+ width: number;
43
+ height: number;
44
+ generated: Record<string, OgImageEntryLike>;
45
+ };
46
+ type OgFontRoleLike = {
47
+ family: string;
48
+ files?: ReadonlyArray<{
49
+ data: string;
50
+ path?: string;
51
+ probe?: string;
52
+ style: "normal" | "italic";
53
+ weight: number;
54
+ }>;
55
+ sourceType: "google" | "local";
56
+ };
57
+
58
+ export type { OgManifestLike as O };
package/dist/search.js CHANGED
@@ -16,11 +16,11 @@ import {
16
16
  } from "react";
17
17
 
18
18
  // src/lib/hosting/framework-paths.ts
19
- var FRAMEWORK_PREFIX = "/publishos", ASSET_PREFIX = `${FRAMEWORK_PREFIX}/assets`, SITE_API_PREFIX = `${FRAMEWORK_PREFIX}/api`, PAGEFIND_PREFIX = `${ASSET_PREFIX}/pagefind`, PAGEFIND_MODULE_URL = `${PAGEFIND_PREFIX}/pagefind.js`, PAGEFIND_ENTRY_URL = `${PAGEFIND_PREFIX}/pagefind-entry.json`, IMAGE_OPTIMIZER_PATH = `${SITE_API_PREFIX}/image`;
20
- var OG_SERVICE_PREFIX = `${SITE_API_PREFIX}/og`, PUBLIC_ASSET_DIRECTORY = "publishos/assets", PUBLIC_FONT_DIRECTORY = `${PUBLIC_ASSET_DIRECTORY}/_publishos/fonts`, PUBLIC_PAGEFIND_DIRECTORY = `public/${PUBLIC_ASSET_DIRECTORY}/pagefind`, FRAMEWORK_PROXY_MATCHER = `/((?!${FRAMEWORK_PREFIX.slice(1)}(?:/|$)|_next/static|_next/image|_next/webpack-hmr).*)`;
19
+ var FRAMEWORK_PREFIX = "/publishos", SOURCE_ASSET_PREFIX = `${FRAMEWORK_PREFIX}/assets`, INTERNAL_PREFIX = `${FRAMEWORK_PREFIX}/internal`, SITE_API_PREFIX = `${FRAMEWORK_PREFIX}/api`, SEARCH_PREFIX = `${INTERNAL_PREFIX}/search`, PAGEFIND_MODULE_URL = `${SEARCH_PREFIX}/pagefind.js`, PAGEFIND_ENTRY_URL = `${SEARCH_PREFIX}/pagefind-entry.json`, IMAGE_OPTIMIZER_PATH = `${SITE_API_PREFIX}/image`;
20
+ var OG_SERVICE_PREFIX = `${SITE_API_PREFIX}/og`, PUBLIC_INTERNAL_DIRECTORY = INTERNAL_PREFIX.slice(1), PUBLIC_FONT_DIRECTORY = `${PUBLIC_INTERNAL_DIRECTORY}/fonts`, PUBLIC_SEARCH_DIRECTORY = `public/${PUBLIC_INTERNAL_DIRECTORY}/search`, FRAMEWORK_PROXY_MATCHER = `/((?!${FRAMEWORK_PREFIX.slice(1)}(?:/|$)|_next/static|_next/image|_next/webpack-hmr).*)`;
21
21
 
22
22
  // src/modules/search/search.tsx
23
- import { jsx } from "react/jsx-runtime";
23
+ import { jsx } from "@publish.os/nextjs/jsx-runtime";
24
24
  var EMPTY_SEARCH_OUTPUT = {
25
25
  items: [],
26
26
  nextOffset: null,
@@ -176,20 +176,18 @@ async function runPagefindSearch(input) {
176
176
  let status = await fetchSearchStatus(input.signal), blockedByStatus = status ? statusOutput(status) : null;
177
177
  return blockedByStatus || await withPagefindIndex(status?.revision, async (pagefind) => {
178
178
  let limit = normalized.limit ?? DEFAULT_SEARCH_LIMIT, offset = normalized.offset ?? 0, result = await pagefind.search(normalized.q, {
179
- filters: pagefindFilters(normalized.filters),
180
- limit,
181
- offset
179
+ filters: pagefindFilters(normalized.filters)
182
180
  });
183
181
  if (!result) return EMPTY_SEARCH_OUTPUT;
184
- let items = await Promise.all(
185
- result.results.map(
182
+ let total = result.results.length, page = result.results.slice(offset, offset + limit), items = await Promise.all(
183
+ page.map(
186
184
  async (pagefindResult) => toSearchResult({
187
185
  data: await pagefindResult.data(),
188
186
  fallbackId: pagefindResult.id,
189
187
  score: pagefindResult.score
190
188
  })
191
189
  )
192
- ), total = result.unfilteredResultCount ?? items.length, nextOffset = offset + limit < total ? offset + limit : null;
190
+ ), nextOffset = offset + limit < total ? offset + limit : null;
193
191
  return {
194
192
  items,
195
193
  nextOffset,
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/lib/theme/theme-scope.tsx
4
4
  import { createContext, use } from "react";
5
- import { jsx } from "react/jsx-runtime";
5
+ import { jsx } from "@publish.os/nextjs/jsx-runtime";
6
6
  var ROOT_SCOPE = Object.freeze({
7
7
  "data-group": "",
8
8
  "data-theme-root": ""
@@ -116,10 +116,6 @@ type ManifestLike = {
116
116
  attribution?: Record<string, ResolvedAttribution>;
117
117
  contentHash: string;
118
118
  };
119
- type RootPageProps = {
120
- site: SiteData;
121
- tree: TreeNode[];
122
- };
123
119
  type LayoutProps = {
124
120
  children: React.ReactNode;
125
121
  site: SiteData;
@@ -128,20 +124,5 @@ type LayoutProps = {
128
124
  currentPath: string;
129
125
  group: string;
130
126
  };
131
- type PageProps<TMeta extends Record<string, unknown> = Record<string, unknown>> = {
132
- site: SiteData;
133
- tree: TreeNode[];
134
- node: TreeNode;
135
- page: PageData<TMeta>;
136
- currentPath: string;
137
- group: string;
138
- };
139
- type IndexPageProps = {
140
- site: SiteData;
141
- tree: TreeNode[];
142
- node: TreeNode;
143
- currentPath: string;
144
- group: string;
145
- };
146
127
 
147
- export type { IndexPageProps as I, LayoutProps as L, ManifestLike as M, PageStatus as P, ResolvedAttribution as R, PageProps as a, RootPageProps as b };
128
+ export type { LayoutProps as L, ManifestLike as M, PageStatus as P };
@@ -0,0 +1,12 @@
1
+ import { MDXComponents as MDXComponents$1 } from 'mdx/types.js';
2
+ import { ReactNode } from 'react';
3
+
4
+ type MDXComponents = MDXComponents$1;
5
+ type MdxErrorBoundaryProps = {
6
+ errorMessage?: string;
7
+ pageId?: string;
8
+ slug?: string;
9
+ children: ReactNode;
10
+ };
11
+
12
+ export type { MdxErrorBoundaryProps as M, MDXComponents as a };
package/dist/types.d.ts CHANGED
@@ -246,6 +246,7 @@ type PageProps<TMeta extends Record<string, unknown> = Record<string, unknown>>
246
246
  tree: TreeNode[];
247
247
  node: TreeNode;
248
248
  page: PageData<TMeta>;
249
+ markdownRevision?: string;
249
250
  currentPath: string;
250
251
  group: string;
251
252
  };
@@ -1,6 +1,29 @@
1
1
  // src/components/mdx/heading-ids.ts
2
2
  import { isValidElement } from "react";
3
- var SELF_CLOSING_TAG_RE = new RegExp("<[^>]+/>", "g"), PAIRED_TAG_RE = /<\/?\w[^>]*>/g, MDX_BOLD_RE = /\*\*(.*?)\*\*/g, MDX_ITALIC_RE = /\*(.*?)\*/g, MDX_UNDERLINE_BOLD_RE = /__(.*?)__/g, MDX_UNDERLINE_ITALIC_RE = /_(.*?)_/g, MDX_STRIKETHROUGH_RE = /~~(.*?)~~/g, MDX_INLINE_CODE_RE = /`(.*?)`/g, MDX_LINK_RE = /\[(.*?)\]\(.*?\)/g, NON_ALPHANUMERIC_RE = /[^a-z0-9]+/g, LEADING_TRAILING_HYPHEN_RE = /^-+|-+$/g, LEADING_DIGIT_RE = /^(\d)/, HEADING_RE = /^(#{1,6})[ \t]+(.+?)\s*#*\s*$/gm, FENCED_CODE_RE = /```[\s\S]*?```|~~~[\s\S]*?~~~/g;
3
+
4
+ // src/components/mdx/heading-string.ts
5
+ var SELF_CLOSING_TAG_RE = /<[^>]+\/>/g, PAIRED_TAG_RE = /<\/?\w[^>]*>/g, MDX_BOLD_RE = /\*\*(.*?)\*\*/g, MDX_ITALIC_RE = /\*(.*?)\*/g, MDX_UNDERLINE_BOLD_RE = /__(.*?)__/g, MDX_UNDERLINE_ITALIC_RE = /_(.*?)_/g, MDX_STRIKETHROUGH_RE = /~~(.*?)~~/g, MDX_INLINE_CODE_RE = /`(.*?)`/g, MDX_LINK_RE = /\[(.*?)\]\(.*?\)/g, NON_ALPHANUMERIC_RE = /[^a-z0-9]+/g, LEADING_TRAILING_HYPHEN_RE = /^-+|-+$/g, LEADING_DIGIT_RE = /^(\d)/;
6
+ function cleanHeadingString(input) {
7
+ return input.replace(SELF_CLOSING_TAG_RE, "").replace(PAIRED_TAG_RE, "").replace(MDX_BOLD_RE, "$1").replace(MDX_ITALIC_RE, "$1").replace(MDX_UNDERLINE_BOLD_RE, "$1").replace(MDX_UNDERLINE_ITALIC_RE, "$1").replace(MDX_STRIKETHROUGH_RE, "$1").replace(MDX_INLINE_CODE_RE, "$1").replace(MDX_LINK_RE, "$1").trim();
8
+ }
9
+ function headingStringToHTMLId(input) {
10
+ let text = cleanHeadingString(input);
11
+ return text ? text.toLowerCase().replace(NON_ALPHANUMERIC_RE, "-").replace(LEADING_TRAILING_HYPHEN_RE, "").replace(LEADING_DIGIT_RE, "id-$1") || "heading" : "empty-heading";
12
+ }
13
+ function createHeadingStringIdGenerator() {
14
+ let nextSuffix = /* @__PURE__ */ new Map(), usedIds = /* @__PURE__ */ new Set();
15
+ return (input) => {
16
+ let baseId = headingStringToHTMLId(input);
17
+ if (baseId === "empty-heading") return baseId;
18
+ let suffix = nextSuffix.get(baseId) ?? 0, id = suffix === 0 ? baseId : `${baseId}-${suffix}`;
19
+ for (; usedIds.has(id); )
20
+ suffix += 1, id = `${baseId}-${suffix}`;
21
+ return nextSuffix.set(baseId, suffix + 1), usedIds.add(id), id;
22
+ };
23
+ }
24
+
25
+ // src/components/mdx/heading-ids.ts
26
+ var HEADING_RE = /^(#{1,6})[ \t]+(.+?)\s*#*\s*$/gm, FENCED_CODE_RE = /```[\s\S]*?```|~~~[\s\S]*?~~~/g;
4
27
  function extractText(node) {
5
28
  if (typeof node == "string") return node;
6
29
  if (typeof node == "number") return String(node);
@@ -14,26 +37,22 @@ function extractText(node) {
14
37
  return "";
15
38
  }
16
39
  function cleanHeadingText(input) {
17
- return (typeof input == "string" ? input : extractText(input)).replace(SELF_CLOSING_TAG_RE, "").replace(PAIRED_TAG_RE, "").replace(MDX_BOLD_RE, "$1").replace(MDX_ITALIC_RE, "$1").replace(MDX_UNDERLINE_BOLD_RE, "$1").replace(MDX_UNDERLINE_ITALIC_RE, "$1").replace(MDX_STRIKETHROUGH_RE, "$1").replace(MDX_INLINE_CODE_RE, "$1").replace(MDX_LINK_RE, "$1").trim();
40
+ let text = typeof input == "string" ? input : extractText(input);
41
+ return cleanHeadingString(text);
18
42
  }
19
43
  function slugify(text) {
20
- return text.toLowerCase().replace(NON_ALPHANUMERIC_RE, "-").replace(LEADING_TRAILING_HYPHEN_RE, "").replace(LEADING_DIGIT_RE, "id-$1");
44
+ return headingStringToHTMLId(text);
21
45
  }
22
46
  function headingToHTMLId(input) {
23
47
  try {
24
- return slugify(cleanHeadingText(input)) || "empty-heading";
48
+ return slugify(cleanHeadingText(input)) || (cleanHeadingText(input) ? "heading" : "empty-heading");
25
49
  } catch {
26
50
  return "empty-heading";
27
51
  }
28
52
  }
29
53
  function createHeadingIdGenerator() {
30
- let usedIds = /* @__PURE__ */ new Map();
31
- return (input) => {
32
- let baseId = headingToHTMLId(input);
33
- if (baseId === "empty-heading") return baseId;
34
- let count = usedIds.get(baseId) ?? 0;
35
- return usedIds.set(baseId, count + 1), count === 0 ? baseId : `${baseId}-${count}`;
36
- };
54
+ let headingId = createHeadingStringIdGenerator();
55
+ return (input) => headingId(cleanHeadingText(input));
37
56
  }
38
57
  function extractMdxHeadings(content = "", levels) {
39
58
  let [minDepth, maxDepth] = levels, headingId = createHeadingIdGenerator(), headings = [], searchableContent = content.replace(FENCED_CODE_RE, "");
@@ -0,0 +1,7 @@
1
+ type HeadingPosition = {
2
+ id: string;
3
+ top: number;
4
+ };
5
+ declare function findActiveHeadingIndex(headings: readonly HeadingPosition[], readingLine: number, isAtBottom?: boolean): number;
6
+
7
+ export { type HeadingPosition, findActiveHeadingIndex };
@@ -0,0 +1,14 @@
1
+ // src/components/block/toc/selection.ts
2
+ function findActiveHeadingIndex(headings, readingLine, isAtBottom = !1) {
3
+ if (headings.length === 0) return -1;
4
+ if (isAtBottom) return headings.length - 1;
5
+ let low = 0, high = headings.length;
6
+ for (; low < high; ) {
7
+ let middle = low + Math.floor((high - low) / 2), heading = headings[middle];
8
+ heading && heading.top <= readingLine ? low = middle + 1 : high = middle;
9
+ }
10
+ return Math.max(0, low - 1);
11
+ }
12
+ export {
13
+ findActiveHeadingIndex
14
+ };
@@ -0,0 +1,16 @@
1
+ import {
2
+ validateLocalSource
3
+ } from "./chunk-ORIUWJBQ.js";
4
+ import "./chunk-NNBJZPFM.js";
5
+ import "./chunk-F3AGNDF4.js";
6
+ import "./chunk-7NY22B5U.js";
7
+ import "./chunk-UYGCOWRF.js";
8
+ import "./chunk-EFO6AWXN.js";
9
+ import "./chunk-5KAD7W53.js";
10
+ import "./chunk-WL75GQ5M.js";
11
+ import "./chunk-AI2UULNX.js";
12
+ import "./chunk-5J3YUNRY.js";
13
+ import "./chunk-22RSSUNV.js";
14
+ export {
15
+ validateLocalSource
16
+ };
@@ -0,0 +1,14 @@
1
+ import {
2
+ validatePublishOsSource
3
+ } from "./chunk-F3AGNDF4.js";
4
+ import "./chunk-7NY22B5U.js";
5
+ import "./chunk-UYGCOWRF.js";
6
+ import "./chunk-EFO6AWXN.js";
7
+ import "./chunk-5KAD7W53.js";
8
+ import "./chunk-WL75GQ5M.js";
9
+ import "./chunk-AI2UULNX.js";
10
+ import "./chunk-5J3YUNRY.js";
11
+ import "./chunk-22RSSUNV.js";
12
+ export {
13
+ validatePublishOsSource
14
+ };
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1600" height="800" viewBox="0 0 1600 800" fill="none">
2
+ <rect width="1600" height="800" fill="#101214"/>
3
+ <g stroke="#343A40" stroke-width="2">
4
+ <path d="M160 240H1440M160 320H1440M160 480H1440M160 560H1440"/>
5
+ <path d="M160 400H560C640 400 640 280 720 280H880C960 280 960 400 1040 400H1440"/>
6
+ <path d="M160 400H560C640 400 640 520 720 520H880C960 520 960 400 1040 400H1440"/>
7
+ </g>
8
+ <path d="M160 400H1440" stroke="#A9CFFF" stroke-width="3"/>
9
+ <circle cx="800" cy="400" r="50" fill="#101214" stroke="#A9CFFF" stroke-width="3"/>
10
+ <path d="m786 383-17 17 17 17m28-34 17 17-17 17" stroke="#A9CFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
11
+ <g fill="#727C86"><circle cx="160" cy="240" r="4"/><circle cx="160" cy="320" r="4"/><circle cx="160" cy="480" r="4"/><circle cx="160" cy="560" r="4"/></g>
12
+ <circle cx="160" cy="400" r="4" fill="#A9CFFF"/>
13
+ </svg>
@@ -0,0 +1,13 @@
1
+ <svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="512" height="512" rx="120" fill="#181818"/>
3
+ <rect x="6" y="6" width="500" height="500" rx="114" stroke="white" stroke-opacity="0.18" stroke-width="12"/>
4
+ <g clip-path="url(#clip0_1715_626)">
5
+ <path d="M273.137 237.996L306.335 157.85L343.538 173.259L310.7 252.535L372.044 191.192L400.518 219.666L339.839 280.343L419.988 247.145L435.398 284.348L307.078 337.498L312.354 339.684H196.574L201.851 337.498L73.5332 284.348L88.9434 247.145L166.473 279.258L106.881 219.666L135.354 191.192L194.937 250.774L162.829 173.259L200.032 157.85L232.869 237.124V152.184H273.137V237.996Z" fill="white"/>
6
+ <rect x="68.5" y="319.551" width="375" height="40.2685" fill="white"/>
7
+ </g>
8
+ <defs>
9
+ <clipPath id="clip0_1715_626">
10
+ <rect width="375" height="375" fill="white" transform="translate(68.5 68.5)"/>
11
+ </clipPath>
12
+ </defs>
13
+ </svg>
@@ -0,0 +1,13 @@
1
+ <svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="512" height="512" rx="120" fill="white"/>
3
+ <rect x="6" y="6" width="500" height="500" rx="114" stroke="#291E00" stroke-opacity="0.2" stroke-width="12"/>
4
+ <g clip-path="url(#clip0_1715_611)">
5
+ <path d="M273.137 237.996L306.335 157.85L343.538 173.259L310.7 252.535L372.044 191.192L400.518 219.666L339.839 280.343L419.988 247.145L435.398 284.348L307.078 337.498L312.354 339.684H196.574L201.851 337.498L73.5332 284.348L88.9434 247.145L166.473 279.258L106.881 219.666L135.354 191.192L194.937 250.774L162.829 173.259L200.032 157.85L232.869 237.124V152.184H273.137V237.996Z" fill="#161000"/>
6
+ <rect x="68.5" y="319.551" width="375" height="40.2685" fill="#161000"/>
7
+ </g>
8
+ <defs>
9
+ <clipPath id="clip0_1715_611">
10
+ <rect width="375" height="375" fill="white" transform="translate(68.5 68.5)"/>
11
+ </clipPath>
12
+ </defs>
13
+ </svg>
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: Hello, world.
3
+ description: Publish your first post and make this blog your own.
4
+ publishedAt: 2026-10-20
5
+ authors: [Matthew B]
6
+ tags: [Press]
7
+ image:
8
+ src: /assets/blog/hello-world.svg
9
+ alt: A code symbol where several publishing paths meet.
10
+ ---
11
+
12
+ Use this blog to share news, releases, and what you learn. Edit this post in `publish.os/blog/content/hello-world.mdx`.
13
+
14
+ ## Add a post
15
+
16
+ Create another `.mdx` file in `publish.os/blog/content/`:
17
+
18
+ ```mdx
19
+ ---
20
+ title: A small beginning
21
+ description: Why this project exists.
22
+ publishedAt: 2026-10-21
23
+ authors: [Matthew B]
24
+ ---
25
+
26
+ This project starts with one problem and one useful solution.
27
+ ```
28
+
29
+ The blog index shows published posts, newest first. Set `publishedAt` to edit the publication date.
30
+
31
+ ## Customize the blog
32
+
33
+ Edit `index.tsx` to change the post list at `/blog`. Edit `page.tsx` to change individual posts. The shared [theme](/docs/themes) supplies colors and typography.
34
+
35
+ ```txt
36
+ publish.os/blog/
37
+ ├── layout.tsx
38
+ ├── index.tsx
39
+ ├── page.tsx
40
+ └── content/
41
+ ├── hello-world.mdx
42
+ └── series-a.mdx
43
+ ```
44
+
45
+
46
+ Edit `layout.tsx` to change the blog layout.
47
+
48
+ Add `tags` and an `image` with `src` and `alt` to a post's frontmatter to customize its header. Keep local images in `publish.os/assets/` and reference them with `/assets/` paths.
@@ -0,0 +1,11 @@
1
+ ---
2
+ title: Our $5M Series A
3
+ description: A fictional funding announcement for your starter blog.
4
+ publishedAt: 2026-10-18
5
+ authors: [Matthew B]
6
+ tags: [Company news]
7
+ ---
8
+
9
+ Example Co. raised $5 million in Series A funding to help teams publish useful documentation. We will use the investment to grow the team and improve the product.
10
+
11
+ This is a fictional announcement for the starter site. Replace it with your own news.
@@ -0,0 +1,82 @@
1
+ import type {
2
+ IndexPageProps,
3
+ PageNode,
4
+ TreeNode,
5
+ } from "@publish.os/nextjs/types";
6
+ import { prettyDate } from "@publish.os/nextjs/utils/pretty-date";
7
+ import Link from "next/link";
8
+
9
+ function pageNodes(nodes: TreeNode[]): PageNode[] {
10
+ return nodes.flatMap((node) => {
11
+ if (node.type === "page") return [node];
12
+ if (node.type === "section" || node.type === "folder") {
13
+ return pageNodes(node.children);
14
+ }
15
+ return [];
16
+ });
17
+ }
18
+
19
+ export default function BlogIndex({ node, tree }: IndexPageProps) {
20
+ const posts = pageNodes(tree)
21
+ .filter((page) => page.status === "published")
22
+ .sort(
23
+ (a, b) =>
24
+ (b.publishedAt ?? "").localeCompare(a.publishedAt ?? "") ||
25
+ a.path.localeCompare(b.path),
26
+ );
27
+
28
+ return (
29
+ <section className="w-full px-4 py-12 md:px-5 lg:px-6 lg:py-16">
30
+ <h1 className="mb-10 text-balance text-5xl font-medium leading-none tracking-tight text-foreground-1">
31
+ {node.title}
32
+ </h1>
33
+ {posts.length > 0 ? (
34
+ <ul>
35
+ {posts.map((post) => {
36
+ const authors = post.authors
37
+ .map((author) => author.name)
38
+ .join(", ");
39
+ const date = prettyDate(post.publishedAt);
40
+
41
+ return (
42
+ <li
43
+ className="border-b border-stroke-4 last:border-b-0"
44
+ key={post.path}
45
+ >
46
+ <Link
47
+ className="-mx-4 flex min-h-12 items-center gap-6 rounded-card px-4 py-4 text-sm text-foreground-1 hover:bg-surface-hover active:bg-surface-active focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-stroke"
48
+ href={post.path}
49
+ title={post.title}
50
+ >
51
+ <span className="min-w-0 flex-1 truncate">{post.title}</span>
52
+ <span className="hidden min-w-0 max-w-[45%] items-baseline gap-1.5 text-foreground-3 md:flex">
53
+ {authors ? (
54
+ <span className="truncate">{authors}</span>
55
+ ) : null}
56
+ {authors && date ? <span aria-hidden="true">·</span> : null}
57
+ {date ? (
58
+ <time
59
+ className="shrink-0 whitespace-nowrap"
60
+ dateTime={post.publishedAt}
61
+ >
62
+ {date}
63
+ </time>
64
+ ) : null}
65
+ </span>
66
+ <span
67
+ aria-hidden="true"
68
+ className="shrink-0 text-foreground-2 md:hidden rtl:rotate-180"
69
+ >
70
+ →
71
+ </span>
72
+ </Link>
73
+ </li>
74
+ );
75
+ })}
76
+ </ul>
77
+ ) : (
78
+ <p className="text-sm text-foreground-2">No posts yet.</p>
79
+ )}
80
+ </section>
81
+ );
82
+ }
@@ -0,0 +1,13 @@
1
+ import type { LayoutProps } from "@publish.os/nextjs/types";
2
+
3
+ export default function BlogLayout({ children }: LayoutProps) {
4
+ return (
5
+ <main
6
+ className="mx-auto flex min-h-0 min-w-0 w-full max-w-(--layout-site-max-width) flex-1 flex-col border-x border-stroke-3 bg-surface-1"
7
+ id="main-content"
8
+ tabIndex={-1}
9
+ >
10
+ {children}
11
+ </main>
12
+ );
13
+ }
@@ -0,0 +1,76 @@
1
+ import { CaretLeftIcon } from "@phosphor-icons/react/ssr";
2
+ import { MDX } from "@publish.os/nextjs/mdx";
3
+ import type { PageProps } from "@publish.os/nextjs/types";
4
+ import { prettyDate } from "@publish.os/nextjs/utils/pretty-date";
5
+ import Image from "next/image";
6
+ import Link from "next/link";
7
+ import { CopyLink } from "../components/blog/copy-link";
8
+
9
+ type BlogMeta = {
10
+ image?: { src: string; alt: string };
11
+ };
12
+
13
+ export default function BlogLeaf({ page }: PageProps<BlogMeta>) {
14
+ const authors = page.authors.map((author) => author.name).join(", ");
15
+ const date = prettyDate(page.publishedAt);
16
+
17
+ return (
18
+ <div className="flex min-h-0 min-w-0 flex-1 flex-col px-4 pt-6 md:px-5 lg:px-6 lg:pt-8">
19
+ <nav aria-label="Blog" className="mb-8 lg:mb-12">
20
+ <Link
21
+ className="-ms-2 inline-flex min-h-11 items-center gap-1.5 rounded-button px-2 text-sm text-foreground-3 hover:text-foreground-1 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-stroke"
22
+ href="/blog"
23
+ >
24
+ <CaretLeftIcon
25
+ aria-hidden="true"
26
+ className="size-3.5 shrink-0 rtl:rotate-180"
27
+ />
28
+ Blog
29
+ </Link>
30
+ </nav>
31
+ <article className="mx-auto flex min-w-0 w-full max-w-4xl flex-1 flex-col wrap-anywhere">
32
+ <header>
33
+ <div className="mx-auto w-full max-w-2xl">
34
+ <h1 className="text-balance text-center text-4xl font-medium leading-tight tracking-tight text-foreground-1 md:text-5xl">
35
+ {page.title}
36
+ </h1>
37
+ </div>
38
+ {page.meta.image ? (
39
+ <Image
40
+ alt={page.meta.image.alt}
41
+ className="mt-10 aspect-2/1 w-full rounded-media border border-stroke-3 object-cover"
42
+ height={800}
43
+ priority
44
+ sizes="(max-width: 896px) 100vw, 896px"
45
+ src={page.meta.image.src}
46
+ width={1600}
47
+ />
48
+ ) : null}
49
+ <div className="mx-auto w-full max-w-2xl">
50
+ {page.description ? (
51
+ <p className="mt-12 text-pretty text-center text-base italic leading-7 text-foreground-2">
52
+ {page.description}
53
+ </p>
54
+ ) : null}
55
+ <hr className="my-10 border-stroke-3" />
56
+ </div>
57
+ </header>
58
+ <div className="mx-auto flex w-full max-w-2xl flex-1 flex-col">
59
+ <div className="markdown-prose min-w-0 flex-1">
60
+ <MDX page={page} />
61
+ </div>
62
+ <div className="mx-auto mt-12 mb-24 flex w-full max-w-2xl flex-wrap items-center justify-between gap-3 border-t border-stroke-3 pt-6">
63
+ {authors || date ? (
64
+ <p className="flex flex-wrap items-baseline gap-x-1.5 text-sm text-foreground-3">
65
+ {authors ? <span>{authors}</span> : null}
66
+ {authors && date ? <span aria-hidden="true">·</span> : null}
67
+ {date ? <time dateTime={page.publishedAt}>{date}</time> : null}
68
+ </p>
69
+ ) : null}
70
+ <CopyLink className="ms-auto" path={page.path} />
71
+ </div>
72
+ </div>
73
+ </article>
74
+ </div>
75
+ );
76
+ }
@@ -0,0 +1,64 @@
1
+ "use client";
2
+
3
+ import { Link } from "@components/ui/link";
4
+ import { LinkSimpleIcon } from "@phosphor-icons/react/ssr";
5
+ import { useState } from "react";
6
+
7
+ export function CopyLink({
8
+ className,
9
+ path,
10
+ }: {
11
+ className?: string;
12
+ path: string;
13
+ }) {
14
+ const [status, setStatus] = useState<"idle" | "pending" | "copied" | "error">(
15
+ "idle",
16
+ );
17
+
18
+ async function copyLink() {
19
+ setStatus("pending");
20
+ try {
21
+ await navigator.clipboard.writeText(
22
+ new URL(path, window.location.origin).href,
23
+ );
24
+ setStatus("copied");
25
+ } catch {
26
+ setStatus("error");
27
+ }
28
+ }
29
+
30
+ return (
31
+ <div className={className}>
32
+ <Link
33
+ aria-busy={status === "pending" || undefined}
34
+ className="inline-flex min-h-11 items-center text-foreground-3 hover:text-foreground-1 active:text-foreground-1 motion-safe:transition-[color,scale] motion-safe:duration-150 motion-safe:active:scale-[0.96] motion-reduce:transition-none"
35
+ href={path}
36
+ leftIcon={<LinkSimpleIcon aria-hidden="true" />}
37
+ onClick={(event) => {
38
+ if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
39
+ return;
40
+ event.preventDefault();
41
+ if (status !== "pending") void copyLink();
42
+ }}
43
+ prefetch={false}
44
+ size="xs"
45
+ >
46
+ Copy link
47
+ </Link>
48
+ <p
49
+ className={
50
+ status === "error"
51
+ ? "mt-2 max-w-60 text-sm text-foreground-2"
52
+ : "sr-only"
53
+ }
54
+ role="status"
55
+ >
56
+ {status === "copied"
57
+ ? "Link copied."
58
+ : status === "error"
59
+ ? "Could not copy. Try again, or copy the address from your browser."
60
+ : ""}
61
+ </p>
62
+ </div>
63
+ );
64
+ }
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Get started
3
3
  description: Preview your site and make your first change.
4
- order: 1
5
4
  ---
6
5
 
7
6
  A publishOS site starts with a folder. The `publish.os/` folder contains your content, theme, and configuration.
@@ -30,7 +29,7 @@ Use Markdown for normal text. You can use **bold text**, _italic text_, and `cod
30
29
 
31
30
  You can also use MDX components to add interactive elements to your pages.
32
31
 
33
- Use [callouts](/docs/callouts) to add notes, warnings, and useful context. The callout guide shows every color and style.
32
+ Use the [blog](/blog) to share updates alongside your documentation.
34
33
 
35
34
  You can show a keyboard shortcut such as <kbd>Ctrl</kbd>+<kbd>Enter</kbd>.
36
35
 
@@ -47,4 +46,4 @@ description: Add a page to your site.
47
46
  Each MDX file contains one page.
48
47
  ```
49
48
 
50
- Next try creating or modifying <a href="/docs/groups">groups</a> or customizing your <a href="/docs/themes">theme</a>.
49
+ Next, organize your [groups](/docs/groups) or customize your [theme](/docs/themes).