CMS for Flutter
Noma helps Flutter teams deliver app content with API-first control, secure backend boundaries, multilingual support, and release-safe publishing operations.
Why Flutter teams use Noma
Flutter apps move fast across iOS and Android, but content updates should not require a full mobile release. Noma provides structured content, locale-aware delivery, assets, and explicit publish workflows for safer updates.
This guide complements CMS for mobile apps and CMS for React Native with Flutter-specific architecture.
Use a mobile backend boundary
Keep Noma credentials in your backend service, not in the Flutter app. Your app calls your mobile API, and the mobile API calls Noma with server-side credentials.
// backend/lib/noma.ts (Node service)
import { createClient } from "@nomacms/js-sdk";
export function getNomaServerClient() {
const projectId = process.env.NOMA_PROJECT_ID;
const apiKey = process.env.NOMA_API_KEY;
if (!projectId || !apiKey) throw new Error("Missing Noma env vars");
return createClient({ projectId, apiKey });
}// backend/routes/flutter-home-feed.ts
import type { Request, Response } from "express";
import { getNomaServerClient } from "../lib/noma";
export async function flutterHomeFeed(req: Request, res: Response) {
const locale = String(req.query.locale ?? "en");
const noma = getNomaServerClient();
const result = await noma.content.list("home_feed", {
state: "published",
locale,
paginate: 20,
sort: "created_at:desc",
});
const items = "data" in result ? result.data : result;
res.json({ items });
}This pattern centralizes auth checks, payload shaping, caching, and abuse protection for all clients.
Repository pattern for Flutter UX
Follow a local-first repository approach: show cached content quickly, refresh in background, then update UI state. This is the same strategy recommended in Flutter offline-first docs.
// lib/data/home_feed_repository.dart
class HomeFeedRepository {
final HomeFeedApi api;
final LocalStore store;
HomeFeedRepository({required this.api, required this.store});
// Local-first read, then background refresh.
Future<List<FeedItem>> getHomeFeed(String locale) async {
final cached = await store.readHomeFeed(locale);
if (cached.isNotEmpty) {
unawaited(_refresh(locale));
return cached;
}
return _refresh(locale);
}
Future<List<FeedItem>> _refresh(String locale) async {
final fresh = await api.fetchHomeFeed(locale);
await store.writeHomeFeed(locale, fresh);
return fresh;
}
}// Pseudocode sync flow
// 1) Read cached content immediately.
// 2) Fetch latest payload from mobile API.
// 3) Update local store.
// 4) Notify UI via state management (Bloc, Riverpod, etc).Official reference: Flutter offline-first support.
Multilingual content delivery
Use locale-scoped reads so each app market receives the right content payload. Combine this with translation-aware modeling in Noma to avoid duplicate content structures.
Related: CMS for multilingual sites.
Secure token and session handling
Keep social login token exchange and JWT issuance on your backend. In Flutter, store sensitive session secrets in secure storage libraries backed by iOS Keychain and Android Keystore.
Avoid putting long-lived auth tokens in plain local preference storage used for non-sensitive app data.
Publish and rollback safely
Content for onboarding, pricing, and promotions often changes faster than app binaries. Noma supports patch, publish, version inspection, and fast rollback flows.
// backend/content-release.ts
const noma = getNomaServerClient();
await noma.content.patch("app_config", configUuid, {
data: { paywall_message: "New annual plan available" },
});
await noma.content.publish("app_config", configUuid);
const versions = await noma.content.versions.list("app_config", configUuid);
await noma.content.versions.revert("app_config", configUuid, versions[0].uuid);Flutter content ops with MCP
Teams can automate locale setup, bulk content updates, and QA tasks using @nomacms/mcp-server and reusable workflows from Agent Skills.
Before production launch
- Keep Noma API keys server-only and out of Flutter bundles.
- Use published state and explicit locale in production content reads.
- Implement local-first reads with background refresh for weak networks.
- Store auth secrets in secure storage, not plain preferences.
- Test content rollback workflows before app release windows.