Skip to main content

Overview

Dynamic strings allow you to update your web app’s text content instantly without deploying new code. Change marketing copy, fix typos, run time-sensitive campaigns, or adjust messaging—all from the Stringboot Dashboard.

Key Benefits

Instant Updates

Change text content without code deploys

Offline-First

Strings cached in IndexedDB—works offline

React Hooks

useString for automatic updates

Zero Dependencies

Lightweight 6.6 kB gzipped SDK

Quick Start

1. Add String to Dashboard

Go to Stringboot DashboardStringsAdd New String:
  • Key: welcome_message
  • Value: "Welcome to our app!"
  • Language: en

2. Use in Your App

3. Update from Dashboard

Go to Strings → Edit welcome_message → Change to "Welcome back!"Save Your app automatically shows the new text next time it syncs.

String Retrieval Methods

useString - Single String

import { useString } from '@stringboot/web-sdk/react';

function ProductTitle() {
  const title = useString('product_title');

  return <h2>{title}</h2>;
}
Benefits:
  • Automatically updates when language changes
  • Updates when network sync completes
  • Zero boilerplate

useStrings - Multiple Strings

import { useStrings } from '@stringboot/web-sdk/react';

function ProductCard() {
  const strings = useStrings(['product_title', 'product_description', 'button_buy']);

  return (
    <div>
      <h2>{strings.product_title}</h2>
      <p>{strings.product_description}</p>
      <button>{strings.button_buy}</button>
    </div>
  );
}
Benefits:
  • Fetch multiple strings efficiently
  • Single hook for all strings in component
  • Returns object with key-value pairs

2. Vanilla JavaScript

Get String (Async)

const text = await StringBoot.get('welcome_message');
// Returns: "Welcome to our app!"
Full Signature:
const text = await StringBoot.get(
  key,           // string key
  lang           // optional language code (defaults to current)
);

Watch for Changes (Reactive)

// Start watching
StringBoot.watch('welcome_message', (value) => {
  document.getElementById('welcome').textContent = value;
});

// Stop watching
StringBoot.unwatch('welcome_message');
Benefits:
  • Automatically updates when string changes
  • Perfect for vanilla JS apps
  • Lifecycle management needed

3. Get Multiple Strings

const keys = ['title', 'subtitle', 'description'];
const strings = await StringBoot.getMultiple(keys);

console.log(strings.title);        // "Product Title"
console.log(strings.subtitle);     // "Amazing product"
console.log(strings.description);  // "Full description"
React version:
const strings = useStrings(['title', 'subtitle', 'description']);

Advanced Patterns

String Templates with Formatting

Dashboard String:
Key: welcome_user
Value: "Welcome back, %s! You have %d new messages."
React Code:
function WelcomeMessage({ userName, messageCount }) {
  const template = useString('welcome_user');
  const formattedText = template
    .replace('%s', userName)
    .replace('%d', messageCount.toString());

  return <p>{formattedText}</p>;
}
Vanilla JS:
const template = await StringBoot.get('welcome_user');
const text = template
  .replace('%s', userName)
  .replace('%d', messageCount);

element.textContent = text;

Manual Sync

Trigger a manual sync to get latest strings:
// Vanilla JS
await StringBoot.sync();

// React Hook
import { useSync } from '@stringboot/web-sdk/react';

function RefreshButton() {
  const { sync, syncing } = useSync();

  return (
    <button onClick={sync} disabled={syncing}>
      {syncing ? 'Syncing...' : 'Refresh Content'}
    </button>
  );
}

Clear Cache

StringBoot.clearCache();
Useful for debugging or forcing a fresh fetch from server.

React Patterns

Component with Loading State

import { useString } from '@stringboot/web-sdk/react';

function ProductTitle() {
  const title = useString('product_title');

  if (!title) {
    return <div>Loading...</div>;
  }

  return <h1>{title}</h1>;
}

Dynamic Content

function OfferBanner({ daysRemaining }) {
  const template = useString('offer_expires');
  const text = template.replace('%d', daysRemaining.toString());

  return (
    <div className="banner">
      <p>{text}</p>
    </div>
  );
}

Lists

function ProductList({ products }) {
  const addToCartText = useString('button_add_to_cart');
  const outOfStockText = useString('label_out_of_stock');

  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>
          <h3>{product.name}</h3>
          <p>${product.price}</p>
          <button disabled={!product.inStock}>
            {product.inStock ? addToCartText : outOfStockText}
          </button>
        </li>
      ))}
    </ul>
  );
}

Next.js Patterns

App Router (Server Components)

app/product/[id]/page.tsx
import { cookies } from 'next/headers';

async function getStrings(lang: string) {
  // Fetch strings server-side
  const res = await fetch(`https://api.stringboot.com/strings?lang=${lang}`, {
    headers: {
      'Authorization': `Bearer ${process.env.STRINGBOOT_API_TOKEN}`
    }
  });
  return res.json();
}

export default async function ProductPage() {
  const cookieStore = cookies();
  const lang = cookieStore.get('language')?.value || 'en';
  const strings = await getStrings(lang);

  return (
    <div>
      <h1>{strings.product_title}</h1>
      <p>{strings.product_description}</p>
    </div>
  );
}

App Router (Client Components)

import { useString } from '@stringboot/web-sdk/react';

export default function ProductTitle() {
  const title = useString('product_title');
  return <h1>{title}</h1>;
}

Best Practices

Recommended:
const title = useString('product_title');
Avoid:
const [title, setTitle] = useState('');

useEffect(() => {
  StringBoot.get('product_title').then(setTitle);
}, []);
Hooks handle updates and lifecycle automatically.
Recommended:
const strings = useStrings(['title', 'subtitle', 'description']);
Avoid:
const title = useString('title');
const subtitle = useString('subtitle');
const description = useString('description');
Single hook is more efficient.
Vanilla JS:
const watchers = [];

// Add watcher
watchers.push('welcome_message');
StringBoot.watch('welcome_message', updateUI);

// Cleanup
function cleanup() {
  watchers.forEach(key => StringBoot.unwatch(key));
}
React hooks handle this automatically.

Common Use Cases

Marketing Campaigns

CampaignBanner.jsx
import { useStrings } from '@stringboot/web-sdk/react';

function CampaignBanner() {
  const strings = useStrings([
    'campaign_banner_title',
    'campaign_banner_subtitle',
    'campaign_cta_button'
  ]);

  return (
    <div className="campaign-banner">
      <h2>{strings.campaign_banner_title}</h2>
      <p>{strings.campaign_banner_subtitle}</p>
      <button>{strings.campaign_cta_button}</button>
    </div>
  );
}
Update campaign text from dashboard—no code changes!

Seasonal Content

import { useString } from '@stringboot/web-sdk/react';

function SeasonalGreeting() {
  const greeting = useString('seasonal_greeting');
  return <h1>{greeting}</h1>;
}
Dashboard (update as seasons change):
  • December: “Happy Holidays!”
  • January: “Happy New Year!”
  • Spring: “Spring Sale!”

Fix Typos Instantly

Found a typo? Fix it in the dashboard and users see the correction immediately on next page load.

Next Steps


API Reference

Core Methods

MethodDescriptionReturns
get(key, lang?)Get string asynchronouslyPromise<string>
getMultiple(keys, lang?)Get multiple stringsPromise<Record<string, string>>
watch(key, callback)Watch for changesvoid
unwatch(key)Stop watchingvoid
sync()Manual sync with serverPromise<void>
clearCache()Clear local cachevoid

React Hooks

HookDescriptionReturns
useString(key)Get single stringstring
useStrings(keys)Get multiple stringsRecord<string, string>
useSync()Manual sync control{ sync, syncing }

Troubleshooting

Check:
  • Is SDK initialized?
  • Did you call sync() after dashboard update?
  • Check browser DevTools → Network for API calls
Solution:
await StringBoot.sync();
Check:
  • Did you initialize SDK with useStringBoot at app root?
  • Is component inside the initialized app tree?
Solution:
App.jsx
import { useStringBoot } from '@stringboot/web-sdk/react';

function App() {
  const { initialized } = useStringBoot({
    apiToken: 'YOUR_TOKEN',
    baseUrl: 'https://api.stringboot.com'
  });

  if (!initialized) return <div>Loading...</div>;
  return <YourApp />;
}

Support