@crowdin/serverless-apps-sdk
v0.21.0
Published
Typed SDK for building serverless Crowdin apps.
Readme
Crowdin Serverless Apps SDK
Typed SDK for building serverless Crowdin apps — frontend-only apps that run inside the Crowdin UI. The SDK is your bundle's connection to Crowdin: it registers the app's modules, exposes typed context, events, and host actions, and ships a Crowdin REST API client that works without tokens, a UI kit styled to match Crowdin, and an i18n runtime.
:bookmark: See the documentation for more information.
Installation
npm install @crowdin/serverless-apps-sdkreact, react-dom, and the Lingui packages are optional peer dependencies: the core entry point works without them; install them to use the /react, /ui, or /i18n entry points. Apps scaffolded with @crowdin/serverless-apps-cli come with all of this preconfigured.
Entry points
| Import | Contents |
|--------|----------|
| @crowdin/serverless-apps-sdk | Framework-free core: module registration (prepare*), getContext(), host events and actions, editor/project/profile/modal APIs |
| @crowdin/serverless-apps-sdk/react | AppUiProvider, useCrowdinContext, useCrowdinEvent, useTheme |
| @crowdin/serverless-apps-sdk/ui | React component library styled to match the Crowdin UI (also re-exports /react) |
| @crowdin/serverless-apps-sdk/ui/theme.css | Tailwind theme source — for apps that run Tailwind CSS themselves (CLI-built apps do) |
| @crowdin/serverless-apps-sdk/ui/styles.css | Prebuilt stylesheet — for apps that do not use Tailwind |
| @crowdin/serverless-apps-sdk/i18n | AppI18nProvider — Lingui-powered translations of your app's own UI |
| @crowdin/serverless-apps-sdk/api | createCrowdinClient() — Crowdin REST API client executed by the host |
| @crowdin/serverless-apps-sdk/manifest.schema.json | JSON Schema for manifest.json |
Registering modules
One bundle serves every module your manifest declares. Register each module at the top level of the entry file with the matching prepare* function; when Crowdin renders the app, the SDK invokes the registered module that matches the host context:
import { prepareProjectMenu } from "@crowdin/serverless-apps-sdk";
import { createRoot } from "react-dom/client";
import { App } from "./App";
prepareProjectMenu({
render() {
createRoot(document.getElementById("root")!).render(<App />);
},
});- Registration must happen synchronously at the top level of the bundle — not inside an async callback.
- If the manifest declares several modules of the same type, pass the module key as the second argument:
prepareProjectMenu({ … }, "my-key").
| Manifest module type | Function |
|----------------------|----------|
| editor-right-panel | prepareEditorRightPanel |
| editor-translations-panel | prepareEditorTranslationsPanel |
| editor-asset-panel | prepareEditorAssetPanel |
| editor-background-worker | prepareEditorBackgroundWorker |
| project-tools | prepareProjectTools |
| project-menu | prepareProjectMenu |
| project-menu-crowdsource | prepareProjectMenuCrowdsource |
| project-reports | prepareProjectReports |
| project-integrations | prepareProjectIntegrations |
| profile-resources-menu | prepareProfileResourcesMenu |
| profile-settings-menu | prepareProfileSettingsMenu |
| organization-menu | prepareOrganizationMenu |
| organization-settings-menu | prepareOrganizationSettingsMenu |
| organization-menu-crowdsource | prepareOrganizationMenuCrowdsource |
| modal | prepareModal |
| chat | prepareChat |
| context-menu | prepareContextMenu |
| navbar-extension | prepareNavbarExtension |
Context, theme, and events
import {
AppUiProvider,
useCrowdinContext,
useCrowdinEvent,
} from "@crowdin/serverless-apps-sdk/react";
function App() {
return (
<AppUiProvider>
<Panel />
</AppUiProvider>
);
}
function Panel() {
const context = useCrowdinContext();
useCrowdinEvent("language.change", () => {
// refresh whatever depends on the selected language
});
return <p>Project: {context.project?.id}</p>;
}AppUiProvider syncs the host theme: it toggles dark mode and applies Crowdin's CSS variables, so the /ui components automatically match the Crowdin look. Outside the Crowdin host, components fall back to default colors.
The framework-free core offers the same capabilities without React: getContext(), getTheme(), onThemeChange(), events.on(), plus typed host APIs such as editor, project, profile, and modal.
Crowdin API
import { createCrowdinClient } from "@crowdin/serverless-apps-sdk/api";
const client = createCrowdinClient();
const strings = await client.sourceStringsApi.listProjectStrings(projectId);createCrowdinClient() returns a @crowdin/crowdin-api-client instance whose requests are executed by the Crowdin host under the current user's session — no tokens ever reach the app. Access is limited to the scopes declared in the manifest. The bridge proxies the REST API only: GraphQL and binary file uploads are not available.
Translating your app (i18n)
The /i18n entry pairs with the CLI's i18n pipeline: write strings with Lingui macros, run crowdin-serverless-apps extract, and the translation catalogs from locales/*.po ship with your bundle. At runtime, AppI18nProvider detects the Crowdin user's locale and loads the matching catalog:
import { AppI18nProvider } from "@crowdin/serverless-apps-sdk/i18n";
import { Trans } from "@lingui/react/macro";
function Root() {
return (
<AppI18nProvider fallback={<p>Loading…</p>}>
<Trans>Hello from my app!</Trans>
</AppI18nProvider>
);
}If no catalog exists for the user's locale, the source locale is used (default en-US, configurable via the sourceLocale prop).
Manifest
manifest.json describes the app. Point $schema at the bundled JSON Schema to get validation and autocomplete in your editor:
{
"$schema": "./node_modules/@crowdin/serverless-apps-sdk/manifest.schema.json",
"name": "My App",
"bundle": { "mode": "internal" },
"scopes": ["project:read"],
"modules": {
"project-menu": [{ "key": "menu", "name": "My App" }]
}
}scopes controls what the in-app API client may do on the user's behalf (an empty array means no API access). bundle.mode is managed for you by the CLI's dev and publish commands.
Seeking Assistance
Found a bug, need help, or have a question? Please contact Customer Success Service.
License
MIT
