Skip to content

fix(examples): restore Vercel workspace deployments - #1908

Merged
eoinest merged 6 commits into
mainfrom
e/multi/fix-vercel-workspace-installs
Jul 17, 2026
Merged

fix(examples): restore Vercel workspace deployments#1908
eoinest merged 6 commits into
mainfrom
e/multi/fix-vercel-workspace-installs

Conversation

@eoinest

@eoinest eoinest commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • make the two connected Vercel example projects install through Corepack and pnpm 10.20.0 so workspace:* dependencies resolve from the monorepo
  • initialize the Vite example through the current initializeGTSPA workspace API before rendering

Testing

  • cd examples/vite-create-app && corepack pnpm --version — passed (10.20.0)
  • cd examples/vite-create-app && corepack pnpm install --frozen-lockfile — passed and linked all 47 workspace projects
  • cd examples/next-gt-starter && corepack pnpm install --frozen-lockfile — passed and linked all 47 workspace projects
  • pnpm --filter vite-create-app typecheck — passed
  • pnpm exec turbo run typecheck --filter=next-starter — passed
  • pnpm --filter vite-create-app lint — passed
  • pnpm exec oxfmt --check examples/vite-create-app/package.json examples/vite-create-app/src/main.tsx examples/vite-create-app/vercel.json examples/next-gt-starter/package.json examples/next-gt-starter/vercel.json — passed
  • pnpm --filter vite-create-app exec vite build — passed
  • pnpm --filter next-starter exec next build — passed

Notes

  • Changeset: not required because only example app deployment configuration and initialization changed.
  • The local Vite bundle check skipped gt translate to avoid creating translation jobs.
  • Vercel project settings now include source files outside each app root so the root lockfile and workspace packages are available.
  • Direct Vercel previews passed: Next starter and Vite.

Greptile Summary

This PR fixes Vercel workspace deployments for both the next-gt-starter and vite-create-app examples by switching to Corepack-managed pnpm so workspace:* dependencies resolve correctly from the monorepo root lockfile.

  • Adds \"packageManager\": \"pnpm@10.20.0\" to both example package.json files and new vercel.json files that set installCommand to corepack pnpm install --frozen-lockfile and route builds through Turbo.
  • Refactors vite-create-app/src/main.tsx from the old GTProvider JSX wrapper pattern to the initializeGTSPA SPA-init API, which blocks rendering until translations are loaded; a .catch() handler logs failures to console.error so the promise rejection is no longer silently swallowed.
  • The next-gt-starter build command additionally installs the Rust stable toolchain with the wasm32-wasip1 target before invoking turbo run build, which is required by a WASM-compiled dependency in the workspace.

Confidence Score: 5/5

Safe to merge — changes are confined to example app deployment config and initialization, with no impact on library packages or production code paths.

All five changed files are in example apps only. The Corepack/pnpm pinning correctly restores workspace resolution, the new vercel.json files follow standard Vercel configuration patterns, and the main.tsx refactor properly uses the SPA init API with credentials auto-read from environment variables via addRuntimeCredentials.

No files require special attention.

Important Files Changed

Filename Overview
examples/vite-create-app/src/main.tsx Switches from GTProvider wrapper to initializeGTSPA SPA pattern; error handling added via .catch(); projectId/devApiKey no longer passed explicitly but are auto-read via addRuntimeCredentials from VITE_GT_PROJECT_ID/VITE_GT_DEV_API_KEY
examples/vite-create-app/vercel.json New file configuring Vercel to use corepack pnpm install and turbo build, enabling workspace:* resolution
examples/next-gt-starter/vercel.json New file adding build/install commands; build installs Rust stable with wasm32-wasip1 target before running turbo build
examples/next-gt-starter/package.json Adds packageManager field (pnpm@10.20.0) required for Corepack to resolve the correct pnpm version on Vercel
examples/vite-create-app/package.json Adds packageManager field (pnpm@10.20.0) required for Corepack to resolve the correct pnpm version on Vercel

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Browser
    participant main.tsx
    participant initializeGTSPA
    participant addRuntimeCredentials
    participant BrowserI18nCache
    participant App

    Browser->>main.tsx: load module
    main.tsx->>initializeGTSPA: call with gtConfig + loadTranslations
    initializeGTSPA->>addRuntimeCredentials: read VITE_GT_PROJECT_ID / VITE_GT_DEV_API_KEY from import.meta.env
    addRuntimeCredentials-->>initializeGTSPA: merged config
    initializeGTSPA->>BrowserI18nCache: initialize i18n cache
    initializeGTSPA->>initializeGTSPA: getTranslationsSnapshot (await locale)
    initializeGTSPA-->>main.tsx: translations ready
    main.tsx->>App: dynamic import('./App.tsx')
    App-->>main.tsx: App component
    main.tsx->>Browser: "createRoot().render(<App />)"
    Note over main.tsx,Browser: .catch() logs console.error on any failure
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Browser
    participant main.tsx
    participant initializeGTSPA
    participant addRuntimeCredentials
    participant BrowserI18nCache
    participant App

    Browser->>main.tsx: load module
    main.tsx->>initializeGTSPA: call with gtConfig + loadTranslations
    initializeGTSPA->>addRuntimeCredentials: read VITE_GT_PROJECT_ID / VITE_GT_DEV_API_KEY from import.meta.env
    addRuntimeCredentials-->>initializeGTSPA: merged config
    initializeGTSPA->>BrowserI18nCache: initialize i18n cache
    initializeGTSPA->>initializeGTSPA: getTranslationsSnapshot (await locale)
    initializeGTSPA-->>main.tsx: translations ready
    main.tsx->>App: dynamic import('./App.tsx')
    App-->>main.tsx: App component
    main.tsx->>Browser: "createRoot().render(<App />)"
    Note over main.tsx,Browser: .catch() logs console.error on any failure
Loading

Reviews (3): Last reviewed commit: "fix(examples): expose Vercel build envir..." | Re-trigger Greptile

Comment thread examples/vite-create-app/src/main.tsx Outdated
@eoinest

eoinest commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai

@eoinest

eoinest commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai

@eoinest
eoinest merged commit 9af15cf into main Jul 17, 2026
29 checks passed
@eoinest
eoinest deleted the e/multi/fix-vercel-workspace-installs branch July 17, 2026 03:15
JoshKappler added a commit that referenced this pull request Jul 22, 2026
Addition, take or leave. One of five SPA example PRs from this morning's
list (webpack #1944, rollup #1945, react-router #1946, rsbuild #1951 on
top of the compiler adapter #1950).

## Summary

- New example `examples/vite-spa`: the finished product of the React SPA
Quickstart plus the "Developing with SPA translations" guide, built to
follow the docs faithfully so docs and example can't drift apart.
- Runtime story: `src/index.ts` awaits `initializeGTSPA` then
dynamically imports the app, so module-level `t()` resolves. No
provider. `<T>`, `t()`, and `<LocaleSelector>` all demonstrated.
- Buildtime story: the compiler's `vite` plugin with
`parsingFlags.devHotReload`, matching vite-create-app.
- Hand-written translation files under `src/_gt/` are keyed by the real
content hashes, so language switching works offline with no account or
API key. `npm run build` runs offline; a separate `translate` script
regenerates the files with a production key.
- `vercel.json` ships an SPA fallback rewrite so deployed deep links and
locale-switch reloads resolve.

## Testing

- typecheck, oxlint, offline build, and a frozen-lockfile install all
pass on the current head.
- Injected `_hash` values in the built bundle match the committed
fixture keys, with the compiler on and with it removed (runtime hashing
computes the same keys).
- Headless Chromium: switching the LocaleSelector rendered en, es, and
ja correctly with zero console errors.
- CI lints examples but does not build them, so the build evidence above
is from manual runs.

## Notes

- This is a second Vite example on purpose: vite-create-app shows GT
retrofitted onto a create-vite scaffold, vite-spa is the from-scratch
docs companion. Both READMEs say which to use. If one Vite example is
enough, happy to fold or drop this one.
- Docs gap found while building, filed separately: the dev guide never
mentions `parsingFlags.devHotReload`, but module-level `t()` strings
won't hot-reload without it.
- No changeset (example only, matches #1908/#1927).

<!-- greptile_comment -->

<h3>Greptile Summary</h3>

This PR adds a new `examples/vite-spa` example — the finished product of
the React SPA Quickstart — demonstrating `gt-react` in a
client-side-only Vite app. The runtime story uses top-level `await
initializeGTSPA()` before dynamically importing `main.tsx`, so
module-level `` t`...` `` calls in `navigation.ts` resolve correctly.
Hand-written translation fixture files in `src/_gt/` enable offline
switching across four locales without an API key.

- **`src/index.ts`**: Imports `gt-react/macros`, awaits
`initializeGTSPA` (passing config + env vars), then dynamically imports
`./main` — ensuring GT is fully initialized before the component tree
renders.
- **`src/loadTranslations.ts`**: Dynamic-imports the per-locale JSON at
runtime, returning `{}` on any missing locale so the app degrades
gracefully.
- **Root `.oxlintrc.json`**: Adds `t` as a global `readonly` identifier
so the monorepo-wide `no-undef` rule does not flag the implicit `t`
macro in `navigation.ts`.

<details open><summary><h3>Confidence Score: 5/5</h3></summary>

Safe to merge. The new example is a self-contained addition with no
changes to production library code, and the one shared-config tweak is
additive.

All source changes are confined to the new examples/vite-spa directory.
The only repo-wide modification is adding t to the oxlint globals block,
which is additive and doesn't affect runtime behavior or library
packages. The initialization sequence (macros → initializeGTSPA →
dynamic import of main) is architecturally sound, offline build is
verified, and the lockfile correctly reflects the package.json
dependency placement.

.oxlintrc.json — the t global is broader than needed; worth scoping to
SPA examples via an override, but not a blocker.
</details>

<details><summary><h3>Important Files Changed</h3></summary>

| Filename | Overview |
|----------|----------|
| examples/vite-spa/src/index.ts | Entry module: correctly sequences
macro import, initializeGTSPA await, and dynamic app import to guarantee
GT is ready before any module-level t`` calls execute. |
| examples/vite-spa/src/navigation.ts | Uses implicit global t`` macro
(attached by gt-react/macros in index.ts); intentional SPA-only pattern,
well-documented in README. |
| examples/vite-spa/src/loadTranslations.ts | Dynamic-imports locale
JSON from src/_gt/; returns {} on missing locale. console.warn is
explicitly allowed by the no-console lint rule. |
| .oxlintrc.json | Adds 't' as a monorepo-wide readonly global so CI
no-undef checks pass for navigation.ts; broader than strictly necessary
since t is only a valid implicit global in SPA entry contexts. |
| examples/vite-spa/vite.config.ts | Wires react() and
gtCompiler(gtConfig) plugins; dedupe for react/react-dom handles
workspace-link resolution correctly. |
| examples/vite-spa/vercel.json | Uses turbo build command with
--env-mode=loose; includes SPA fallback rewrite; matches conventions of
sibling examples. |
| examples/vite-spa/package.json | gt is correctly placed under
devDependencies (matches its lockfile placement); gt-react in
dependencies; all workspace:* pins consistent. |
| examples/vite-spa/gt.config.json | Configures defaultLocale, four
target locales, output path, and parsingFlags.devHotReload for
hot-reload of module-level t`` strings during development. |

</details>

<details><summary><h3>Sequence Diagram</h3></summary>

```mermaid
sequenceDiagram
    participant Browser
    participant index.ts
    participant loadTranslations.ts
    participant _gt/[locale].json
    participant initializeGTSPA
    participant main.tsx
    participant App

    Browser->>index.ts: load (module script)
    index.ts->>index.ts: import 'gt-react/macros' (attaches global t``)
    index.ts->>initializeGTSPA: "await initializeGTSPA({ ...gtConfig, projectId, devApiKey, loadTranslations })"
    initializeGTSPA->>loadTranslations.ts: call loadTranslations(locale)
    loadTranslations.ts->>_gt/[locale].json: dynamic import
    _gt/[locale].json-->>loadTranslations.ts: translation map
    loadTranslations.ts-->>initializeGTSPA: resolved translations
    initializeGTSPA-->>index.ts: resolved
    index.ts->>main.tsx: await import('./main')
    main.tsx->>App: createRoot().render(App)
    App->>App: navigation uses t`Home`, t`About` (resolved)
    App->>App: Welcome renders T and LocaleSelector
```
</details>

<sub>Reviews (7): Last reviewed commit: ["fix(examples): use the global
t macro
an..."](3535245)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=45751551)</sub>

<!-- /greptile_comment -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants