@botlr/next 0.0.0-stage → 0.2.0

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # @botlr/next
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Page helpers extracted from the satellite apps.
8
+
9
+ `@botlr/sdk`: `PageResponse` gains optional `full_slug`, `breadcrumbs` and `alternate_translations` (new `AlternateTranslation` type, also used by `ResolveResponse`). New asset helpers `getAssetUrl`, `createAssetUrl`, `getAssetId`, `getAssetFilename` and `isAssetData` take the media server URL explicitly instead of reading `NEXT_PUBLIC_MEDIA_URL`.
10
+
11
+ `@botlr/next`: `resolvePage` and `createPageResolver`, `buildPageMetadata`, `renderCmsPage` with `themeSettingsToCss`, `serveStaticTextFile` and `defaultRobotsContent`, `createLocalePage` and `createLocaleAliasPage`, `rateLimit` and `getClientIp`, plus `scopeFromEnv` and `environmentFromEnv`. Every helper takes its client and component registry as arguments. `html-react-parser` is a new dependency.
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+ - @botlr/sdk@0.2.0
17
+ - @botlr/react@0.1.1
18
+
19
+ ## 0.1.0
20
+
21
+ - First release. `getBotlrForRoute` moves here from the publisher's
22
+ `lib/botlr-sdk/server.ts`, typed against `@botlr/sdk`, plus
23
+ `getCachedBotlr`, `createBotlrFromEnv`, `configFromEnv` and
24
+ `localeFromAcceptLanguage`.
25
+ - Re-exports `@botlr/react` and the `@botlr/sdk` types.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Botlr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,84 @@
1
- # Temporary Holding Version
1
+ # @botlr/next
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Next.js helpers on top of `@botlr/sdk` and `@botlr/react`. Everything from
4
+ both packages is re-exported, so a server file can import from `@botlr/next`
5
+ alone. The package imports `next/headers` and `next/navigation`, so client
6
+ components should import runtime values from `@botlr/sdk` or `@botlr/react`
7
+ instead; type imports from `@botlr/next` are fine anywhere.
8
+
9
+ ## Clients
10
+
11
+ - `getBotlrForRoute(params)` builds a client for the current request. The
12
+ locale comes from `Accept-Language` unless given; `baseUrl`, `apiKey` and
13
+ `appId` fall back to `BOTLR_API_URL`, `BOTLR_API_KEY` and `BOTLR_APP_ID`.
14
+ All of them are server-side variables: the API URL is never exposed to the
15
+ browser through a `NEXT_PUBLIC_` name.
16
+ - `getCachedBotlr` is the same, memoised per request with React `cache`.
17
+ - `createBotlrFromEnv(overrides)` needs no request context (scripts,
18
+ `generateStaticParams`, the page helpers below).
19
+ - `configFromEnv`, `scopeFromEnv({ locale })` (from `BOTLR_ORG_SLUG`,
20
+ `BOTLR_PROJECT_SLUG`, `BOTLR_APP_INSTANCE_SLUG`, `BOTLR_APP_ID`),
21
+ `environmentFromEnv()` (`BOTLR_ENVIRONMENT`, `ENVIRONMENT`, `NODE_ENV`) and
22
+ `localeFromAcceptLanguage` are the building blocks.
23
+
24
+ ## A static locale route in one call
25
+
26
+ ```ts
27
+ // lib/botlr.ts
28
+ import { createBotlrFromEnv } from "@botlr/next";
29
+ export const botlr = createBotlrFromEnv();
30
+
31
+ // app/(root)/[[...slug]]/page.tsx
32
+ import { createLocalePage } from "@botlr/next";
33
+ import { botlr } from "@/lib/botlr";
34
+ import { publisherSectionRegistry } from "@/components/sections/publisher-section-registry";
35
+
36
+ // Segment config must stay as literals here so Next can read it statically.
37
+ export const revalidate = false;
38
+ export const dynamicParams = false;
39
+
40
+ const page = createLocalePage({
41
+ locale: "da",
42
+ folder: "",
43
+ client: botlr,
44
+ componentRegistry: publisherSectionRegistry,
45
+ siteUrl: process.env.NEXT_PUBLIC_APP_URL,
46
+ });
47
+
48
+ export const generateStaticParams = page.generateStaticParams;
49
+ export const generateMetadata = page.generateMetadata;
50
+ export default page.Page;
51
+ ```
52
+
53
+ `createLocalePage` lists slugs with `getPageSlugList`, resolves each request
54
+ once for metadata and page through `createPageResolver`, calls `notFound()`
55
+ for missing and unpublished pages, follows CMS redirects with
56
+ `permanentRedirect` (or `redirect` with `redirect: "temporary"`) prefixed by
57
+ `folder`, and renders with `renderCmsPage`. `createLocaleAliasPage("/sv")`
58
+ makes a folder that only redirects to another one.
59
+
60
+ ## The pieces
61
+
62
+ - `resolvePage(client, slug, locale, options)` folds `/api/resolve` into
63
+ `{ kind: "page" | "redirect" | "404" | "error" }` and prepends non-page
64
+ content (articles by default; see `contentSections`) to the `main` region as
65
+ an inline section. `createPageResolver(client, options)` binds the client
66
+ and memoises per request.
67
+ - `buildPageMetadata(pageData, { siteUrl, folder })` turns `seo_meta` into
68
+ Next `Metadata`: title, description, keywords, Open Graph, Twitter, robots,
69
+ canonical and hreflang alternates. Without `siteUrl` only an explicit
70
+ `seo_meta.canonical` is emitted.
71
+ - `renderCmsPage({ pageData, scope, componentRegistry, client })` picks the
72
+ page template, then the theme's, then a built-in one; merges template and
73
+ page layouts; applies visibility rules for `environment`; fetches shared
74
+ sections through `client` or `fetchSharedSection`; and mounts a
75
+ `SectionRenderer` at every `{{{REGION}}}` marker. `themeSettingsToCss`
76
+ emits the theme's custom properties.
77
+ - `serveStaticTextFile(client, slug, defaultContent)` serves a CMS page's
78
+ text sections as `text/plain`, for `robots.txt`, `humans.txt` and
79
+ `llms.txt` routes. `defaultRobotsContent()` allows everything in production
80
+ and disallows elsewhere.
81
+ - `rateLimit(key, { limit, window })` and `getClientIp(request)` for form and
82
+ forum route handlers. In-memory, per server instance.
83
+
84
+ `next` and `react` are peer dependencies; `html-react-parser` is a dependency.