@bleedingdev/modern-js-create 3.2.0-ultramodern.3 → 3.2.0-ultramodern.30

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 (68) hide show
  1. package/README.md +32 -14
  2. package/dist/index.js +2753 -324
  3. package/dist/types/locale/en.d.ts +2 -0
  4. package/dist/types/locale/zh.d.ts +2 -0
  5. package/dist/types/ultramodern-workspace.d.ts +13 -0
  6. package/package.json +8 -5
  7. package/template/.agents/skills-lock.json +34 -0
  8. package/template/.github/renovate.json +53 -0
  9. package/template/.github/workflows/ultramodern-gates.yml.handlebars +34 -10
  10. package/template/.mise.toml.handlebars +2 -0
  11. package/template/AGENTS.md +27 -0
  12. package/template/README.md +20 -14
  13. package/template/api/effect/index.ts.handlebars +7 -45
  14. package/template/config/public/locales/cs/translation.json +39 -0
  15. package/template/config/public/locales/en/translation.json +39 -0
  16. package/template/modern.config.ts.handlebars +44 -23
  17. package/template/oxfmt.config.ts +8 -0
  18. package/template/oxlint.config.ts +12 -0
  19. package/template/package.json.handlebars +59 -30
  20. package/template/pnpm-workspace.yaml +26 -0
  21. package/template/rstest.config.mts +7 -0
  22. package/template/scripts/bootstrap-agent-skills.mjs +95 -0
  23. package/template/scripts/check-i18n-strings.mjs +83 -0
  24. package/template/scripts/validate-ultramodern.mjs.handlebars +438 -16
  25. package/template/shared/effect/api.ts.handlebars +1 -2
  26. package/template/src/modern-app-env.d.ts +2 -0
  27. package/template/src/modern.runtime.ts.handlebars +17 -3
  28. package/template/src/routes/[lang]/page.tsx.handlebars +210 -0
  29. package/template/src/routes/index.css.handlebars +14 -3
  30. package/template/src/routes/layout.tsx.handlebars +2 -1
  31. package/template/tests/tsconfig.json +7 -0
  32. package/template/tests/ultramodern.contract.test.ts.handlebars +78 -0
  33. package/template/tsconfig.json +106 -2
  34. package/template-workspace/.agents/agent-reference-repos.json +24 -0
  35. package/template-workspace/.agents/rstackjs-agent-skills-LICENSE +21 -0
  36. package/template-workspace/.agents/skills/rsbuild-best-practices/SKILL.md +57 -0
  37. package/template-workspace/.agents/skills/rsdoctor-analysis/SKILL.md +96 -0
  38. package/template-workspace/.agents/skills/rsdoctor-analysis/references/command-map.md +113 -0
  39. package/template-workspace/.agents/skills/rsdoctor-analysis/references/common-analysis-patterns.md +190 -0
  40. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +88 -0
  41. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +138 -0
  42. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +71 -0
  43. package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor.md +39 -0
  44. package/template-workspace/.agents/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +103 -0
  45. package/template-workspace/.agents/skills/rslib-best-practices/SKILL.md +58 -0
  46. package/template-workspace/.agents/skills/rslib-modern-package/SKILL.md +173 -0
  47. package/template-workspace/.agents/skills/rspack-best-practices/SKILL.md +70 -0
  48. package/template-workspace/.agents/skills/rspack-tracing/SKILL.md +75 -0
  49. package/template-workspace/.agents/skills/rspack-tracing/references/bottlenecks.md +47 -0
  50. package/template-workspace/.agents/skills/rspack-tracing/references/tracing-guide.md +38 -0
  51. package/template-workspace/.agents/skills/rspack-tracing/scripts/analyze_trace.js +184 -0
  52. package/template-workspace/.agents/skills/rstest-best-practices/SKILL.md +133 -0
  53. package/template-workspace/.agents/skills-lock.json +114 -0
  54. package/template-workspace/.github/renovate.json +29 -0
  55. package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +54 -0
  56. package/template-workspace/.gitignore.handlebars +5 -0
  57. package/template-workspace/.mise.toml.handlebars +2 -0
  58. package/template-workspace/AGENTS.md +61 -0
  59. package/template-workspace/README.md.handlebars +26 -5
  60. package/template-workspace/oxfmt.config.ts +16 -0
  61. package/template-workspace/oxlint.config.ts +19 -0
  62. package/template-workspace/pnpm-workspace.yaml +34 -8
  63. package/template-workspace/scripts/assert-mf-types.mjs +44 -0
  64. package/template-workspace/scripts/bootstrap-agent-skills.mjs +155 -0
  65. package/template-workspace/scripts/setup-agent-reference-repos.mjs +364 -0
  66. package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +755 -87
  67. package/template/biome.json +0 -41
  68. package/template/src/routes/page.tsx.handlebars +0 -119
@@ -35,6 +35,7 @@ export declare const EN_LOCALE: {
35
35
  optionUltramodernPackageSource: string;
36
36
  optionUltramodernPackageScope: string;
37
37
  optionUltramodernPackageNamePrefix: string;
38
+ optionMicroVertical: string;
38
39
  optionSub: string;
39
40
  examples: string;
40
41
  example1: string;
@@ -47,6 +48,7 @@ export declare const EN_LOCALE: {
47
48
  example8: string;
48
49
  example9: string;
49
50
  example10: string;
51
+ example11: string;
50
52
  moreInfo: string;
51
53
  };
52
54
  version: {
@@ -35,6 +35,7 @@ export declare const ZH_LOCALE: {
35
35
  optionUltramodernPackageSource: string;
36
36
  optionUltramodernPackageScope: string;
37
37
  optionUltramodernPackageNamePrefix: string;
38
+ optionMicroVertical: string;
38
39
  optionSub: string;
39
40
  examples: string;
40
41
  example1: string;
@@ -47,6 +48,7 @@ export declare const ZH_LOCALE: {
47
48
  example8: string;
48
49
  example9: string;
49
50
  example10: string;
51
+ example11: string;
50
52
  moreInfo: string;
51
53
  };
52
54
  version: {
@@ -1,8 +1,10 @@
1
+ export type MicroVerticalKind = 'remote' | 'horizontal-remote' | 'service' | 'shared';
1
2
  type UltramodernPackageSourceStrategy = 'workspace' | 'install';
2
3
  export type UltramodernWorkspaceOptions = {
3
4
  targetDir: string;
4
5
  packageName: string;
5
6
  modernVersion: string;
7
+ enableTailwind?: boolean;
6
8
  packageSource?: {
7
9
  strategy?: UltramodernPackageSourceStrategy;
8
10
  modernPackageVersion?: string;
@@ -11,10 +13,21 @@ export type UltramodernWorkspaceOptions = {
11
13
  aliasPackageNamePrefix?: string;
12
14
  };
13
15
  };
16
+ export type AddUltramodernMicroVerticalOptions = {
17
+ workspaceRoot: string;
18
+ name: string;
19
+ kind: MicroVerticalKind;
20
+ modernVersion: string;
21
+ enableTailwind?: boolean;
22
+ packageSource?: UltramodernWorkspaceOptions['packageSource'];
23
+ };
14
24
  export declare const ULTRAMODERN_WORKSPACE_FLAG = "--ultramodern-workspace";
25
+ export declare function addUltramodernMicroVertical(options: AddUltramodernMicroVerticalOptions): void;
15
26
  export declare function generateUltramodernWorkspace(options: UltramodernWorkspaceOptions): void;
16
27
  export declare const ultramodernWorkspaceVersions: {
17
28
  tanstackRouter: string;
18
29
  moduleFederation: string;
30
+ tailwind: string;
31
+ tailwindPostcss: string;
19
32
  };
20
33
  export {};
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "engines": {
22
22
  "node": ">=20"
23
23
  },
24
- "version": "3.2.0-ultramodern.3",
24
+ "version": "3.2.0-ultramodern.30",
25
25
  "types": "./dist/types/index.d.ts",
26
26
  "main": "./dist/index.js",
27
27
  "bin": {
@@ -38,10 +38,10 @@
38
38
  ],
39
39
  "devDependencies": {
40
40
  "@rslib/core": "0.21.5",
41
- "@types/node": "^25.8.0",
42
- "@typescript/native-preview": "7.0.0-dev.20260516.1",
43
- "tsx": "^4.22.0",
44
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.3"
41
+ "@types/node": "^25.9.1",
42
+ "@typescript/native-preview": "7.0.0-dev.20260527.2",
43
+ "tsx": "^4.22.3",
44
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.30"
45
45
  },
46
46
  "publishConfig": {
47
47
  "registry": "https://registry.npmjs.org/",
@@ -52,5 +52,8 @@
52
52
  "build": "rslib build && pnpm -w tsgo:dts \"$PWD\"",
53
53
  "dev": "rslib build -w",
54
54
  "start": "node ./dist/index.js"
55
+ },
56
+ "ultramodern": {
57
+ "frameworkVersion": "3.2.0-ultramodern.30"
55
58
  }
56
59
  }
@@ -0,0 +1,34 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "installDir": ".agents/skills",
4
+ "sources": [
5
+ {
6
+ "id": "techsiocz-private",
7
+ "visibility": "private",
8
+ "repository": "https://github.com/TechsioCZ/skills",
9
+ "install": "clone-if-authorized",
10
+ "baseline": [
11
+ {
12
+ "name": "plan-graph",
13
+ "reason": "Build and validate DAGs from .plan.md files"
14
+ },
15
+ {
16
+ "name": "dag",
17
+ "reason": "Inspect current plan frontiers and blocked lanes"
18
+ },
19
+ {
20
+ "name": "subagent-graph",
21
+ "reason": "Design dependency-aware multi-agent launch graphs"
22
+ },
23
+ {
24
+ "name": "helm",
25
+ "reason": "Steer already-running multi-agent work"
26
+ },
27
+ {
28
+ "name": "debugger-mode",
29
+ "reason": "Run hypothesis-driven debugging with runtime evidence"
30
+ }
31
+ ]
32
+ }
33
+ ]
34
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:recommended",
5
+ "helpers:pinGitHubActionDigests"
6
+ ],
7
+ "dependencyDashboard": true,
8
+ "minimumReleaseAge": "1 day",
9
+ "prConcurrentLimit": 5,
10
+ "prHourlyLimit": 2,
11
+ "rangeStrategy": "bump",
12
+ "schedule": [
13
+ "before 5am on monday"
14
+ ],
15
+ "timezone": "Etc/UTC",
16
+ "packageRules": [
17
+ {
18
+ "matchManagers": [
19
+ "github-actions"
20
+ ],
21
+ "groupName": "github-actions",
22
+ "labels": [
23
+ "dependencies",
24
+ "github-actions",
25
+ "security"
26
+ ]
27
+ },
28
+ {
29
+ "matchManagers": [
30
+ "npm"
31
+ ],
32
+ "matchUpdateTypes": [
33
+ "patch",
34
+ "minor"
35
+ ],
36
+ "groupName": "npm minor and patch updates",
37
+ "labels": [
38
+ "dependencies",
39
+ "npm"
40
+ ]
41
+ },
42
+ {
43
+ "matchUpdateTypes": [
44
+ "major"
45
+ ],
46
+ "dependencyDashboardApproval": true,
47
+ "labels": [
48
+ "dependencies",
49
+ "major"
50
+ ]
51
+ }
52
+ ]
53
+ }
@@ -4,27 +4,51 @@ on:
4
4
  push:
5
5
  pull_request:
6
6
 
7
+ permissions:
8
+ contents: read
9
+
10
+ defaults:
11
+ run:
12
+ shell: bash
13
+
14
+ env:
15
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
16
+
17
+ concurrency:
18
+ group: ultramodern-gates-${{ github.workflow }}-${{ github.ref }}
19
+ cancel-in-progress: true
20
+
7
21
  jobs:
8
22
  ultramodern-gates:
9
23
  runs-on: ubuntu-latest
24
+ timeout-minutes: 20
10
25
  steps:
11
- - name: Checkout
12
- uses: actions/checkout@v4
26
+ - name: Harden Runner
27
+ uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2
28
+ with:
29
+ egress-policy: audit
13
30
 
14
- - name: Setup pnpm
15
- uses: pnpm/action-setup@v4
31
+ - name: Checkout
32
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
33
+ with:
34
+ fetch-depth: 1
35
+ persist-credentials: false
16
36
 
17
37
  - name: Setup Node.js
18
- uses: actions/setup-node@v4
38
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
19
39
  with:
20
- node-version: 20
21
- cache: pnpm
40
+ node-version: 24
41
+
42
+ - name: Setup mise
43
+ uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3.2.0
22
44
 
23
45
  - name: Install Dependencies
24
- run: pnpm install
46
+ run: mise exec -- pnpm install --frozen-lockfile
25
47
 
26
48
  - name: Validate Ultramodern Contract
27
- run: pnpm run ultramodern:check
49
+ run: mise exec -- pnpm run ultramodern:check
28
50
 
29
51
  - name: Build
30
- run: pnpm run build
52
+ env:
53
+ MODERN_PUBLIC_SITE_URL: http://localhost:8080
54
+ run: mise exec -- pnpm run build
@@ -0,0 +1,2 @@
1
+ [tools]
2
+ pnpm = "{{pnpmVersion}}"
@@ -0,0 +1,27 @@
1
+ # UltraModern Agent Contract
2
+
3
+ This project is generated for Codex-first UltraModern.js work.
4
+
5
+ ## Quality Gates
6
+
7
+ - `pnpm lint` runs Oxlint with the Ultracite preset.
8
+ - `pnpm format` runs oxfmt.
9
+ - `pnpm typecheck` runs effect-tsgo as the TypeScript checker.
10
+ - `pnpm i18n:check` rejects hardcoded user-visible JSX text.
11
+ - `mise exec -- pnpm ultramodern:check` verifies the generated contract.
12
+
13
+ ## Internationalization
14
+
15
+ Runtime i18n is enabled by default. Agents must put user-visible UI copy in `config/public/locales/<lang>/translation.json` and render it through `react-i18next` or `@modern-js/plugin-i18n/runtime`. Do not add hardcoded JSX text, `aria-label`, `title`, `alt`, or `placeholder` strings unless the value is a non-translatable technical token.
16
+
17
+ Routes are locale-prefixed by default through `localePathRedirect: true`. Keep localized pages under `src/routes/[lang]`, use links for language switching, and preserve canonical plus `hreflang` metadata. Production builds fail unless `MODERN_PUBLIC_SITE_URL` is set, so deployed canonical URLs always use the production origin.
18
+
19
+ ## Private Skills
20
+
21
+ Private orchestration skills are not vendored into this template. If you are authorized for `TechsioCZ/skills`, run:
22
+
23
+ ```bash
24
+ pnpm skills:install
25
+ ```
26
+
27
+ The installer clones that private repository and copies only the allowlisted skills from `.agents/skills-lock.json`.
@@ -5,7 +5,8 @@
5
5
  Install the dependencies:
6
6
 
7
7
  ```bash
8
- pnpm install
8
+ mise install
9
+ mise exec -- pnpm install
9
10
  ```
10
11
 
11
12
  ## Get Started
@@ -13,19 +14,19 @@ pnpm install
13
14
  Start the dev server:
14
15
 
15
16
  ```bash
16
- pnpm dev
17
+ mise exec -- pnpm dev
17
18
  ```
18
19
 
19
20
  Build the app for production:
20
21
 
21
22
  ```bash
22
- pnpm build
23
+ mise exec -- pnpm build
23
24
  ```
24
25
 
25
26
  Validate the generated Ultramodern preset contract locally:
26
27
 
27
28
  ```bash
28
- pnpm run ultramodern:check
29
+ mise exec -- pnpm run ultramodern:check
29
30
  ```
30
31
 
31
32
  The generated preset defaults are opt-out. Disable specific contracts via env vars:
@@ -36,20 +37,25 @@ MODERN_BASELINE_ENABLE_BFF_REQUEST_ID=false
36
37
  MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS=false
37
38
  ```
38
39
 
39
- The generated starter also includes `.github/workflows/ultramodern-gates.yml`.
40
- That workflow runs `pnpm run ultramodern:check` and `pnpm run build` on every
41
- push and pull request so the `presetUltramodern(...)` contract stays explicit.
40
+ The generated starter also includes `.github/workflows/ultramodern-gates.yml`
41
+ and `.github/renovate.json`. The workflow runs
42
+ `mise exec -- pnpm run ultramodern:check` and `mise exec -- pnpm run build` on
43
+ every push and pull request with read-only permissions, commit-pinned actions,
44
+ frozen installs, and StepSecurity audit-mode runner hardening. Renovate is
45
+ configured for dependency dashboard review, one-day release age, grouped
46
+ updates, action digest pinning, and manual approval for major upgrades.
42
47
 
43
48
  ## Micro Vertical Workspaces
44
49
 
45
- Inside a Micro Vertical workspace, generate shell, remote, and service packages
46
- with `--sub` so the workspace root owns package-manager and CI policy:
50
+ Inside a Micro Vertical workspace, add packages from the workspace root with
51
+ the UltraModern add flow. It derives paths, package names, ports, Module
52
+ Federation names, topology entries, overlays, ownership, and root dev scripts:
47
53
 
48
54
  ```bash
49
- npx @modern-js/create apps/shell --router tanstack --tailwind --workspace --sub
50
- npx @modern-js/create apps/remotes/catalog --router tanstack --tailwind --workspace --sub
51
- npx @modern-js/create apps/remotes/design-system --router tanstack --tailwind --workspace --sub
52
- npx @modern-js/create services/catalog-api --bff-runtime effect --workspace --sub
55
+ mise exec -- pnpm dlx @modern-js/create catalog --microvertical remote
56
+ mise exec -- pnpm dlx @modern-js/create design-system --microvertical horizontal-remote
57
+ mise exec -- pnpm dlx @modern-js/create catalog-api --microvertical service
58
+ mise exec -- pnpm dlx @modern-js/create catalog-contracts --microvertical shared
53
59
  ```
54
60
 
55
61
  The canonical topology is documented in
@@ -71,7 +77,7 @@ Verticals.
71
77
  Preview the production build locally:
72
78
 
73
79
  ```bash
74
- pnpm serve
80
+ mise exec -- pnpm serve
75
81
  ```
76
82
 
77
83
  For more information, see the
@@ -2,60 +2,22 @@
2
2
  Effect,
3
3
  HttpApiBuilder,
4
4
  Layer,
5
- Schema,
6
- ServiceMap,
7
5
  defineEffectBff,
8
6
  } from '@modern-js/plugin-bff/effect-server';
9
7
  import { bffEffectApi } from '../../shared/effect/api';
10
8
 
11
- class GreetingUnavailableError extends Schema.TaggedError<GreetingUnavailableError>()(
12
- 'GreetingUnavailableError',
13
- {
14
- message: Schema.String,
15
- },
16
- ) {}
17
-
18
- class GreetingService extends ServiceMap.Service<GreetingService>()('GreetingService', {
19
- make: Effect.succeed({
20
- hello: Effect.fn('GreetingService.hello')(function* () {
21
- if (Date.now() < 0) {
22
- return yield* Effect.fail(
23
- new GreetingUnavailableError({
24
- message: 'Greeting service is unavailable',
25
- }),
26
- );
27
- }
28
-
29
- return {
30
- message: 'Hello from Effect HttpApi',
31
- runtime: 'effect' as const,
32
- };
33
- }),
34
- }),
35
- }) {
36
- static readonly layer = Layer.effect(this, this.make);
37
- }
38
-
39
- const greetingsLayer = HttpApiBuilder.group(bffEffectApi, 'greetings', handlers =>
9
+ const greetingsLayer = HttpApiBuilder.group(bffEffectApi, 'greetings', (handlers) =>
40
10
  handlers.handle('hello', () =>
41
- GreetingService.use(service => service.hello()).pipe(
42
- Effect.catchTag('GreetingUnavailableError', error =>
43
- Effect.succeed({
44
- message: error.message,
45
- runtime: 'effect' as const,
46
- }),
47
- ),
48
- ),
11
+ Effect.succeed({
12
+ message: 'Hello from Effect HttpApi',
13
+ runtime: 'effect' as const,
14
+ }),
49
15
  ),
50
16
  );
51
17
 
52
- const layer = HttpApiBuilder.layer(bffEffectApi).pipe(
53
- Layer.provide(greetingsLayer),
54
- Layer.provide(GreetingService.layer),
55
- );
18
+ const layer = HttpApiBuilder.layer(bffEffectApi).pipe(Layer.provide(greetingsLayer));
56
19
 
57
20
  export default defineEffectBff({
58
21
  api: bffEffectApi,
59
22
  layer,
60
- });
61
- {{/if}}
23
+ });{{/if}}
@@ -0,0 +1,39 @@
1
+ {
2
+ "home": {
3
+ "bff": {
4
+ "response": "Odpoved Effect HttpApi:"
5
+ },
6
+ "cards": {
7
+ "bff": {
8
+ "body": "Pouzivej Effect jako hlavni BFF cestu, Hono nech jako explicitni zalozni volbu.",
9
+ "title": "BFF + Effect"
10
+ },
11
+ "config": {
12
+ "body": "Upravuj vygenerovane vychozi hodnoty v modern.config.ts.",
13
+ "title": "Konfigurace presetUltramodern"
14
+ },
15
+ "gates": {
16
+ "body": "Starter obsahuje PR workflow pro ultramodern:check a build.",
17
+ "title": "Ultramodern kontroly"
18
+ },
19
+ "guide": {
20
+ "body": "Projdi si verejny preset pripraveny pro MV, TanStack a Effect.",
21
+ "title": "UltraModern.js pruvodce"
22
+ }
23
+ },
24
+ "description": {
25
+ "afterConfig": ", udrzuj",
26
+ "afterPreset": "profil. Zacni v",
27
+ "end": "zelene a lad vygenerovany preset jen tam, kde aplikace potrebuje mekci cestu.",
28
+ "intro": "Tento starter prinasi verejny"
29
+ },
30
+ "language": {
31
+ "cs": "Cestina",
32
+ "en": "Anglictina",
33
+ "switcher": "Jazyk"
34
+ },
35
+ "logoAlt": "Logo UltraModern.js",
36
+ "name": "presetUltramodern",
37
+ "title": "UltraModern.js 3.0"
38
+ }
39
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "home": {
3
+ "bff": {
4
+ "response": "Effect HttpApi response:"
5
+ },
6
+ "cards": {
7
+ "bff": {
8
+ "body": "Keep Effect as the preferred BFF lane while Hono stays an explicit fallback.",
9
+ "title": "BFF + Effect"
10
+ },
11
+ "config": {
12
+ "body": "Tune the generated defaults in modern.config.ts.",
13
+ "title": "Configure presetUltramodern"
14
+ },
15
+ "gates": {
16
+ "body": "The starter includes a PR workflow for ultramodern:check and build.",
17
+ "title": "Ultramodern Gates"
18
+ },
19
+ "guide": {
20
+ "body": "Review the MV-first, TanStack-ready, Effect-ready public preset.",
21
+ "title": "UltraModern.js Guide"
22
+ }
23
+ },
24
+ "description": {
25
+ "afterConfig": ", keep",
26
+ "afterPreset": "profile. Start in",
27
+ "end": "green, and tune the generated preset only where your app needs a softer lane.",
28
+ "intro": "This starter ships the public"
29
+ },
30
+ "language": {
31
+ "cs": "Czech",
32
+ "en": "English",
33
+ "switcher": "Language"
34
+ },
35
+ "logoAlt": "UltraModern.js Logo",
36
+ "name": "presetUltramodern",
37
+ "title": "UltraModern.js 3.0"
38
+ }
39
+ }
@@ -1,41 +1,62 @@
1
+ // @effect-diagnostics nodeBuiltinImport:off processEnv:off
1
2
  import { appTools, defineConfig, presetUltramodern } from '@modern-js/app-tools';
2
3
  import path from 'node:path';
3
4
  {{#if enableBff}}import { bffPlugin } from '@modern-js/plugin-bff';
4
- {{/if}}{{#if isTanstackRouter}}import { tanstackRouterPlugin } from '@modern-js/plugin-tanstack';
5
+ {{/if}}import { i18nPlugin } from '@modern-js/plugin-i18n';
6
+ {{#if isTanstackRouter}}import { tanstackRouterPlugin } from '@modern-js/plugin-tanstack';
5
7
  {{/if}}
6
-
7
- const appId = process.env.MODERN_BASELINE_APP_ID || path.basename(process.cwd());
8
- const enableModuleFederationSSR =
9
- process.env.MODERN_BASELINE_ENABLE_MF_SSR !== 'false';
10
- const enableBffRequestId =
11
- process.env.MODERN_BASELINE_ENABLE_BFF_REQUEST_ID !== 'false';
8
+ const appId = process.env['MODERN_BASELINE_APP_ID'] || path.basename(process.cwd());
9
+ const enableModuleFederationSSR = process.env['MODERN_BASELINE_ENABLE_MF_SSR'] !== 'false';
10
+ const enableBffRequestId = process.env['MODERN_BASELINE_ENABLE_BFF_REQUEST_ID'] !== 'false';
12
11
  const enableTelemetryExporters =
13
- process.env.MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS !== 'false';
14
- const telemetryFailLoudStartup =
15
- process.env.MODERN_TELEMETRY_FAIL_LOUD_STARTUP !== 'false';
12
+ process.env['MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS'] !== 'false';
13
+ const telemetryFailLoudStartup = process.env['MODERN_TELEMETRY_FAIL_LOUD_STARTUP'] !== 'false';
14
+ const otlpEndpoint = process.env['MODERN_TELEMETRY_OTLP_ENDPOINT'];
15
+ const configuredSiteUrl = process.env['MODERN_PUBLIC_SITE_URL'];
16
+ const hasConfiguredSiteUrl = typeof configuredSiteUrl === 'string' && configuredSiteUrl.length > 0;
17
+ const isProductionBuild =
18
+ process.env['NODE_ENV'] === 'production' || process.argv.includes('build');
19
+
20
+ if (isProductionBuild && !hasConfiguredSiteUrl) {
21
+ throw new Error(
22
+ 'MODERN_PUBLIC_SITE_URL must be set for production builds so canonical and hreflang URLs use the deployed origin.',
23
+ );
24
+ }
25
+
26
+ const siteUrl = hasConfiguredSiteUrl ? configuredSiteUrl : 'http://localhost:8080';
27
+ const victoriaMetricsEndpoint = process.env['MODERN_TELEMETRY_VICTORIA_ENDPOINT'];
16
28
 
17
29
  // https://bleedingdev.github.io/ultramodern.js/configure/app/usage.html
18
30
  export default defineConfig(
19
31
  presetUltramodern(
20
32
  {
21
- plugins: [
33
+ {{#if enableBff}} bff: {
34
+ {{#if useEffectBff}} effect: {
35
+ openapi: true,
36
+ },
37
+
38
+ {{/if}} runtimeFramework: '{{bffRuntime}}',
39
+ },
40
+
41
+ {{/if}} plugins: [
22
42
  appTools(),
43
+ i18nPlugin({
44
+ localeDetection: {
45
+ fallbackLanguage: 'en',
46
+ languages: ['en', 'cs'],
47
+ localePathRedirect: true,
48
+ },
49
+ }),
23
50
  {{#if isTanstackRouter}}
24
51
  tanstackRouterPlugin(),
25
52
  {{/if}}{{#if enableBff}}
26
53
  bffPlugin(),
27
- {{/if}}
28
- ],
29
- {{#if enableBff}}
30
- bff: {
31
- runtimeFramework: '{{bffRuntime}}',
32
- {{#if useEffectBff}}
33
- effect: {
34
- openapi: true,
54
+ {{/if}} ],
55
+ source: {
56
+ globalVars: {
57
+ ULTRAMODERN_SITE_URL: siteUrl,
35
58
  },
36
- {{/if}}
37
59
  },
38
- {{/if}}
39
60
  },
40
61
  {
41
62
  appId,
@@ -43,8 +64,8 @@ export default defineConfig(
43
64
  enableModuleFederationSSR,
44
65
  enableTelemetryExporters,
45
66
  telemetryFailLoudStartup,
46
- otlpEndpoint: process.env.MODERN_TELEMETRY_OTLP_ENDPOINT,
47
- victoriaMetricsEndpoint: process.env.MODERN_TELEMETRY_VICTORIA_ENDPOINT,
67
+ ...(typeof otlpEndpoint === 'string' ? { otlpEndpoint } : {}),
68
+ ...(typeof victoriaMetricsEndpoint === 'string' ? { victoriaMetricsEndpoint } : {}),
48
69
  },
49
70
  ),
50
71
  );
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'oxfmt';
2
+ import ultracite from 'ultracite/oxfmt';
3
+
4
+ export default defineConfig({
5
+ extends: [ultracite],
6
+ ignorePatterns: ['dist', 'node_modules', '.modern', '.modernjs', '**/routeTree.gen.ts'],
7
+ singleQuote: true,
8
+ });
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from 'oxlint';
2
+ import core from 'ultracite/oxlint/core';
3
+ import react from 'ultracite/oxlint/react';
4
+
5
+ export default defineConfig({
6
+ env: {
7
+ browser: true,
8
+ node: true,
9
+ },
10
+ extends: [core, react],
11
+ ignorePatterns: ['dist', 'node_modules', '.modern', '.modernjs', '**/routeTree.gen.ts'],
12
+ });