lokalise-prod-checklist
Execute Lokalise production deployment checklist and rollback procedures. Use when deploying Lokalise integrations to production, preparing for launch, or implementing go-live procedures. Trigger with phrases like "lokalise production", "deploy lokalise", "lokalise go-live", "lokalise launch checklist". allowed-tools: Read, Bash(lokalise2:*), Bash(curl:*), Grep version: 1.0.0 license: MIT author: Jeremy Longshore <jeremy@intentsolutions.io>
Allowed Tools
No tools specified
Provided by Plugin
lokalise-pack
Claude Code skill pack for Lokalise (24 skills)
Installation
This skill is included in the lokalise-pack plugin:
/plugin install lokalise-pack@claude-code-plugins-plus
Click to copy
Instructions
# Lokalise Production Checklist
## Overview
Complete checklist for deploying Lokalise integrations to production.
## Prerequisites
- Staging environment tested and verified
- Production API token available
- Deployment pipeline configured
- Monitoring and alerting ready
## Instructions
### Step 1: Pre-Deployment Configuration
- [ ] Production API token stored in secure vault
- [ ] Token has appropriate permissions (read-only if possible for downloads)
- [ ] Environment variables set in deployment platform
- [ ] Webhook endpoints configured with HTTPS
- [ ] Webhook secrets stored securely
### Step 2: Code Quality Verification
- [ ] All tests passing (`npm test`)
- [ ] No hardcoded API tokens or secrets
- [ ] Error handling covers all Lokalise error types (401, 403, 404, 429, 5xx)
- [ ] Rate limiting implemented (6 req/sec)
- [ ] Logging is production-appropriate (no PII, no tokens)
- [ ] TypeScript types are up to date
### Step 3: Translation Quality
- [ ] All base language strings present
- [ ] Critical languages fully translated
- [ ] No missing translations for essential UI
- [ ] Placeholder syntax validated (ICU format)
- [ ] No HTML/script injection in translations
### Step 4: Infrastructure Setup
- [ ] Health check endpoint includes Lokalise connectivity
- [ ] Monitoring/alerting configured for API errors
- [ ] Circuit breaker pattern implemented
- [ ] Graceful degradation for translation failures
- [ ] CDN caching for downloaded translations (if applicable)
### Step 5: Documentation Requirements
- [ ] Incident runbook created
- [ ] Token rotation procedure documented
- [ ] Rollback procedure documented
- [ ] On-call escalation path defined
### Step 6: Deploy with Verification
```bash
#!/bin/bash
# deploy-with-verification.sh
set -e
echo "=== Lokalise Production Deployment ==="
# Pre-flight checks
echo "1. Checking Lokalise API status..."
STATUS=$(curl -s https://api.lokalise.com/api2/system/health | jq -r '.status // "unknown"')
if [ "$STATUS" != "ok" ]; then
echo "ERROR: Lokalise API not healthy. Aborting."
exit 1
fi
echo "2. Verifying API token..."
TOKEN_CHECK=$(curl -s -o /dev/null -w "%{http_code}" \
-H "X-Api-Token: $LOKALISE_API_TOKEN" \
"https://api.lokalise.com/api2/projects?limit=1")
if [ "$TOKEN_CHECK" != "200" ]; then
echo "ERROR: API token invalid (HTTP $TOKEN_CHECK). Aborting."
exit 1
fi
echo "3. Downloading fresh translations..."
npm run i18n:pull
echo "4. Building application..."
npm run build
echo "5. Running post-build tests..."
npm run test:e2e
echo "6. Deploying..."
# Your deployment command here
# vercel --prod / fly deploy / gcloud run deploy
echo "7. Verifying deployment..."
HEALTH=$(curl -s https://your-app.com/api/health | jq -r '.services.translations')
if [ "$HEALTH" != "healthy" ]; then
echo "WARNING: Translation service health check failed"
fi
echo "=== Deployment Complete ==="
```
## Output
- Deployed Lokalise integration
- Health checks passing
- Monitoring active
- Rollback procedure documented
## Error Handling
| Alert | Condition | Severity |
|-------|-----------|----------|
| API Down | 5xx errors > 5/min | P1 |
| Translation Missing | 404 on key lookup | P2 |
| Rate Limited | 429 errors > 10/min | P2 |
| Auth Failures | 401/403 errors > 0 | P1 |
| High Latency | p99 > 3000ms | P3 |
## Examples
### Health Check Implementation
```typescript
interface HealthStatus {
status: "healthy" | "degraded" | "unhealthy";
translations: {
connected: boolean;
latencyMs: number;
lastSync?: string;
};
}
async function checkTranslationHealth(): Promise {
const start = Date.now();
try {
const client = new LokaliseApi({
apiKey: process.env.LOKALISE_API_TOKEN!,
});
// Quick connectivity check
await client.projects().list({ limit: 1 });
return {
status: "healthy",
translations: {
connected: true,
latencyMs: Date.now() - start,
lastSync: process.env.TRANSLATIONS_LAST_SYNC,
},
};
} catch (error) {
return {
status: "degraded",
translations: {
connected: false,
latencyMs: Date.now() - start,
},
};
}
}
// Express health endpoint
app.get("/health", async (req, res) => {
const health = await checkTranslationHealth();
const statusCode = health.status === "healthy" ? 200 : 503;
res.status(statusCode).json(health);
});
```
### Graceful Degradation
```typescript
import en from "./locales/en.json"; // Bundled fallback
async function getTranslations(locale: string): Promise> {
try {
// Try to load from Lokalise/CDN
const response = await fetch(`/locales/${locale}.json`);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
} catch (error) {
console.warn(`Failed to load ${locale}, falling back to English`);
return en;
}
}
```
### Rollback Procedure
```bash
#!/bin/bash
# rollback-translations.sh
# Option 1: Revert to previous Git commit translations
git checkout HEAD~1 -- src/locales/
# Option 2: Download specific snapshot from Lokalise
lokalise2 \
--token "$LOKALISE_API_TOKEN" \
--project-id "$LOKALISE_PROJECT_ID" \
file download \
--format json \
--filter-data reviewed \
--unzip-to ./src/locales
# Rebuild and redeploy
npm run build
npm run deploy
```
### Pre-Production Validation Script
```typescript
async function validateProductionReadiness(): Promise<{
ready: boolean;
issues: string[];
}> {
const issues: string[] = [];
// Check environment
if (!process.env.LOKALISE_API_TOKEN) {
issues.push("LOKALISE_API_TOKEN not set");
}
if (!process.env.LOKALISE_PROJECT_ID) {
issues.push("LOKALISE_PROJECT_ID not set");
}
// Check translations exist
const localeDir = "./src/locales";
const requiredLocales = ["en", "es", "fr", "de"];
for (const locale of requiredLocales) {
const path = `${localeDir}/${locale}.json`;
if (!fs.existsSync(path)) {
issues.push(`Missing locale file: ${locale}.json`);
}
}
// Check for missing translations in non-base languages
const baseTranslations = JSON.parse(
fs.readFileSync(`${localeDir}/en.json`, "utf8")
);
const baseKeys = Object.keys(flattenObject(baseTranslations));
for (const locale of requiredLocales.filter(l => l !== "en")) {
const translations = JSON.parse(
fs.readFileSync(`${localeDir}/${locale}.json`, "utf8")
);
const localeKeys = Object.keys(flattenObject(translations));
const missingKeys = baseKeys.filter(k => !localeKeys.includes(k));
if (missingKeys.length > 0) {
issues.push(`${locale}: ${missingKeys.length} missing translations`);
}
}
return {
ready: issues.length === 0,
issues,
};
}
```
## Resources
- [Lokalise Status](https://status.lokalise.com)
- [Lokalise Support](mailto:support@lokalise.com)
## Next Steps
For version upgrades, see `lokalise-upgrade-migration`.