@uxfront/layer-docs 0.2.0 → 0.2.1

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 CHANGED
@@ -1,6 +1,54 @@
1
1
  # @uxfront/layer-docs
2
2
 
3
- ## 0.1.2
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Stop the optional `posthog-js` peer from killing the client bundle of every consumer that omits it.
8
+
9
+ `app/plugins/posthog.client.ts` imported `posthog-js` statically at module scope while declaring it an **optional** `peerDependency`. Rollup has no module to resolve for a consumer that skipped the optional peer, so it emits the specifier as a module-scope throw:
10
+
11
+ ```js
12
+ const HB = {};
13
+ throw new Error('Could not resolve "posthog-js" imported by "@uxfront/layer-docs".');
14
+ ```
15
+
16
+ That throw runs on evaluation, before the plugin body — so neither the `analytics.enabled` guard nor the `posthog.key` guard ever executed, and the failure was not confined to analytics. The whole client entry died with it: **the site did not hydrate at all**. Every page served as a dead static document — theme toggle stuck on its loading skeleton, framework tabs inert, no client-side routing, `localStorage` never written — with one console error per route as the only signal. Present in `0.1.0`, `0.1.1` and `0.2.0`.
17
+
18
+ `posthog-js` is now imported dynamically, inside the branch that has already confirmed analytics is enabled and a key is provisioned. The unresolvable specifier moves out of the client entry into its own lazy chunk that a consumer without the peer never evaluates — it is emitted, prefetched at most, and never run. The import is also wrapped, which keeps the failure proportional to what failed: a missing or broken module degrades to a console warning and no analytics, instead of a dead app.
19
+
20
+ `modules/optimizeDeps` carried the same assumption from the other direction — it named `posthog-js` in `optimizeDeps.include` unconditionally, which is a hard dev-server error when the package is not installed. The hint is now added only when the dependency actually resolves.
21
+
22
+ Consumers who do not use PostHog need no changes and should upgrade. Consumers who do use it are unaffected: `$posthog()` is provided exactly as before once the client initialises.
23
+
24
+ ## 0.2.0
25
+
26
+ ### Minor Changes
27
+
28
+ - Absorb documentation-site plumbing that consumers were re-declaring by hand.
29
+
30
+ - `defineDocsCollections(sections, options)` gains `{ sitemap?, changelog? }`. With
31
+ `sitemap: true` the landing and docs collections carry `defineSitemapSchema()`;
32
+ with `changelog: true` a `changelog` collection is registered over
33
+ `changelog/*.md`. Both default to `false`, so existing single-argument calls are
34
+ unchanged. Per-locale collections are now gated on `locales.length > 0` rather
35
+ than the array's mere presence.
36
+ - 30 additional locales ship with the layer (ar, be, bn, ca, ckb, cs, da, de, el,
37
+ et, fr, he, hi, hy, it, ja, kk, km, ko, ky, lb, ms, nb, pl, ru, sl, sv, uk, ur,
38
+ vi), each complete against `en.json`.
39
+ - `nuxt.schema.ts` ships with the layer, so the Content Studio preview schema for
40
+ `app.config.ts` is described once instead of per consumer.
41
+ - New `modules/optimizeDeps` module pre-bundles the layer's own heavier runtime
42
+ dependencies; registered automatically.
43
+ - New `DocsAsideLeftTop` / `DocsFrameworkSelect` render a persistent framework
44
+ selector above the sidebar navigation, and `GradientPageHero` puts `UPageHero`
45
+ on `MorphingGradientBackground`. Both render only when the consumer opts in.
46
+
47
+ **Breaking-ish:** `useFramework()` no longer ships a built-in React/Vue/Vanilla
48
+ default list. `frameworks` is now `appConfig.docsTheme.frameworks ?? []`, making
49
+ app config the single source of truth. Sites that relied on the implicit default
50
+ must declare `docsTheme.frameworks` in their own `app.config.ts`; `FrameworkSwitcher`
51
+ renders no tab bar when the list is empty.
4
52
 
5
53
  ### Patch Changes
6
54
 
@@ -10,8 +58,16 @@
10
58
  that `0.1.1` contains accessibility fixes for `button-name` and
11
59
  `nested-interactive` violations. `0.1.1` now has a complete entry, and the
12
60
  `AppHeaderCTA.vue` typecheck fix previously filed under `0.1.2` is recorded
13
- under `0.1.0`, the release it actually shipped in. No runtime code changed in
14
- this release.
61
+ under `0.1.0`, the release it actually shipped in.
62
+
63
+ Note: `0.2.0` was versioned by a hand `chore: bump version` commit that bypassed
64
+ `changeset version`, so it published with no changelog entry at all — the tarball
65
+ topped out at a `## 0.1.2` heading for a version that was versioned but never
66
+ published. The entry above is the accurate, reconstructed record of what `0.2.0`
67
+ actually contains, and the changelog-only correction previously filed under
68
+ `0.1.2` is folded in here because `0.2.0` is the release it shipped in. Every
69
+ heading in this file now corresponds to a version that exists on the registry.
70
+ Second occurrence of UXF-67; see UXF-168.
15
71
 
16
72
  ## 0.1.1
17
73
 
@@ -1,15 +1,14 @@
1
1
  import type { ConfigDefaults } from "posthog-js";
2
- import posthog from "posthog-js";
3
2
  import { defineNuxtPlugin } from "#app";
4
3
 
5
- export default defineNuxtPlugin(() => {
4
+ export default defineNuxtPlugin(async () => {
6
5
  if (import.meta.dev) {
7
- return;
6
+ return {};
8
7
  }
9
8
 
10
9
  // Consumers opt out via `app.config` (`analytics.enabled: false`).
11
10
  if (!useAppConfig().analytics?.enabled) {
12
- return;
11
+ return {};
13
12
  }
14
13
 
15
14
  const runtimeConfig = useRuntimeConfig();
@@ -17,7 +16,27 @@ export default defineNuxtPlugin(() => {
17
16
  // No key provisioned (`NUXT_PUBLIC_POSTHOG_KEY` unset) — no-op instead of
18
17
  // initialising a client that would fire requests at nothing.
19
18
  if (!runtimeConfig.public.posthog.key) {
20
- return;
19
+ return {};
20
+ }
21
+
22
+ // `posthog-js` is an OPTIONAL peer dependency. A static top-level import
23
+ // compiles to a module-scope `throw` for every consumer that omits it, and
24
+ // that throw runs before any of the guards above — killing the entire client
25
+ // bundle, not just analytics, so the site serves as a dead static document.
26
+ // Importing here keeps the unresolvable specifier behind the opt-in, and the
27
+ // catch keeps a missing or broken module a no-analytics degradation rather
28
+ // than a dead app.
29
+ let posthog;
30
+ try {
31
+ ({ default: posthog } = await import("posthog-js"));
32
+ } catch (error) {
33
+ console.warn(
34
+ "[layer-docs] analytics is enabled and a PostHog key is set, but " +
35
+ "`posthog-js` could not be loaded — continuing without analytics. " +
36
+ "Install `posthog-js` to enable it.",
37
+ error,
38
+ );
39
+ return {};
21
40
  }
22
41
 
23
42
  const posthogClient = posthog.init(runtimeConfig.public.posthog.key, {
@@ -1,3 +1,4 @@
1
+ import { createRequire } from "node:module";
1
2
  import { defineNuxtModule, extendViteConfig } from "@nuxt/kit";
2
3
 
3
4
  /**
@@ -13,16 +14,32 @@ export default defineNuxtModule({
13
14
  meta: {
14
15
  name: "optimize-deps",
15
16
  },
16
- setup() {
17
+ setup(_options, nuxt) {
18
+ const include = ["@nuxt/content > slugify", "@vueuse/core", "motion-v"];
19
+
20
+ // `posthog-js` is an OPTIONAL peer. Naming an uninstalled package in
21
+ // `optimizeDeps.include` is a hard dev-server error, so hint it only when
22
+ // the consumer actually has it.
23
+ if (canResolve("posthog-js", nuxt.options.rootDir)) {
24
+ include.push("posthog-js");
25
+ }
26
+
17
27
  extendViteConfig((config) => {
18
28
  config.optimizeDeps ||= {};
19
29
  config.optimizeDeps.include ||= [];
20
- config.optimizeDeps.include.push(
21
- "@nuxt/content > slugify",
22
- "@vueuse/core",
23
- "motion-v",
24
- "posthog-js",
25
- );
30
+ config.optimizeDeps.include.push(...include);
26
31
  });
27
32
  },
28
33
  });
34
+
35
+ function canResolve(id: string, fromDir: string): boolean {
36
+ for (const parent of [`${fromDir}/`, import.meta.url]) {
37
+ try {
38
+ createRequire(parent).resolve(id);
39
+ return true;
40
+ } catch {
41
+ // try the next resolution root
42
+ }
43
+ }
44
+ return false;
45
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxfront/layer-docs",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Neutral, brandable Nuxt-layer documentation theme. Consumers extend it and supply their own branding, content and section topology.",
5
5
  "keywords": [
6
6
  "docs",