From 3225143c4942eca2fcde9936fede773bbe0efb87 Mon Sep 17 00:00:00 2001 From: moss-bryophyta <261561981+moss-bryophyta@users.noreply.github.com> Date: Thu, 19 Mar 2026 08:03:04 -0700 Subject: [PATCH] fix: broken devlog links, stale component path, typo in derive template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "/blog/gt-next_v6_*" → "/devlog/gt-next_v6_*" in 4 files (devlogs, not blog posts) - "/api/components/static" → "/api/components/derive" in derive string template (renamed) - "statment" → "statement" in derive string template --- blog/en-US/t-macro.mdx | 127 ++++++++++++++++++++ docs-templates/api/components/derive.mdx | 2 +- docs-templates/api/strings/derive.mdx | 6 +- docs/en-US/next/guides/cache-components.mdx | 2 +- docs/en-US/next/guides/ssg.mdx | 2 +- 5 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 blog/en-US/t-macro.mdx diff --git a/blog/en-US/t-macro.mdx b/blog/en-US/t-macro.mdx new file mode 100644 index 0000000..e231d74 --- /dev/null +++ b/blog/en-US/t-macro.mdx @@ -0,0 +1,127 @@ +--- +title: "Stop Wrapping Your Strings in Function Calls" +summary: "The new t macro lets you write translated template literals — no ICU syntax, no options objects, no context providers." +date: 2026-03-18 +authors: [ernest] +tags: ['gt-react', 'i18n', 'tagged-template', 'macro', 'developer-experience'] +--- + +## The Problem with `t("Hello, {name}", { name })` + +If you've ever internationalized a React app, you've written something like this: + +```jsx +const gt = useGT(); + +return
{gt("Hello, {name}! You have {count} items.", { name, count })}
; +``` + +It works. But it's clunky. You're writing ICU MessageFormat syntax by hand, duplicating every variable name in the options object, and pulling `t` out of a hook that requires React context. For something that's supposed to be a thin layer over your existing strings, it's a lot of ceremony. + +And it gets worse. The moment you need a translation outside a React component — in a utility function, an event handler, a server action — you're reaching for workarounds, because hooks don't work there. + +## Template literals should just work + +Here's what the same code looks like with the `t` macro: + +```jsx +import { t } from "gt-react/browser"; + +return{t`Hello, ${name}! You have ${count} items.`}
; +``` + +That's it. Standard JavaScript template literal syntax. No ICU placeholders, no options object, no hook, no context provider. You write your string the way you'd write any template literal, and the compiler handles the rest. + +At build time, the GT compiler transforms: + +```js +t`Hello, ${name}!` +``` + +into: + +```js +t("Hello, {0}!", { "0": name }) +``` + +The tagged template is pure syntactic sugar — the runtime behavior is identical to calling `t()` with a string. But the developer experience is dramatically better. + +## No more React context dependency + +The bigger change here isn't syntax — it's architecture. The `t` function exported from `gt-react/browser` doesn't use React context. It doesn't need a hook. It doesn't need to be called inside a component. + +This means you can use `t` in: + +- **Event handlers**: `onClick={() => alert(t`Saved!`)}` +- **Utility functions**: `function formatError(code) { return t`Error: ${code}` }` +- **Constants and config**: `const LABELS = { save: t`Save`, cancel: t`Cancel` }` +- **Anywhere JavaScript runs on the client** + +The old pattern — `useGT()` returning a function scoped to React context — was a bottleneck. It forced translation to be a React concern when it's really a string concern. + +## Global registration + +If you don't want to import `t` in every file, you can register it globally: + +```js +// In your app's entry point +import "gt-react/macros"; +``` + +This sets `globalThis.t`, making the tagged template available everywhere without an import. The compiler is smart enough to detect this — if `t` is already imported from a GT source, it won't inject a duplicate import. If it's not, and you've used `t` as a tagged template, the compiler injects the import for you. + +## Concatenation works too + +The macro expansion isn't limited to tagged templates. It also handles template literals passed as arguments and string concatenation: + +```jsx +// Template literal as argument — also transformed +t(`Welcome back, ${user}`) + +// String concatenation — also transformed +t("Hello, " + name + "! Welcome.") +``` + +Both get normalized to the same `t("...", { ... })` call at build time. + +## Getting started + +### 1. Install the latest version of `gt-react` + +```bash +npm install gt-react@latest +``` + +### 2. Use the `t` macro + +Either import directly: + +```jsx +import { t } from "gt-react/browser"; + +export function Greeting({ name }) { + return{t`Hello, ${name}!`}
; +} +``` + +Or register globally and skip imports: + +```js +// app/layout.tsx or entry point +import "gt-react/macros"; +``` + +```jsx +// Anywhere in your app +export function Greeting({ name }) { + return{t`Hello, ${name}!`}
; +} +``` + +### 3. That's it + +The GT compiler handles the transformation automatically during your build. No additional config is needed — macro expansion is enabled by default. + +--- + +The `t` macro is a small change to the API surface, but it reflects a larger shift: translations should feel native to JavaScript, not like a framework-specific escape hatch. Write your strings naturally. Let the toolchain do the rest. diff --git a/docs-templates/api/components/derive.mdx b/docs-templates/api/components/derive.mdx index 43a7afd..d67c0cf 100644 --- a/docs-templates/api/components/derive.mdx +++ b/docs-templates/api/components/derive.mdx @@ -26,7 +26,7 @@ The `