Noma
Flutter · Mobile CMS · 2026

CMS for Flutter

Noma helps Flutter teams deliver app content with API-first control, secure backend boundaries, multilingual support, and release-safe publishing operations.

Positioning

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.

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.

Offline-first

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.

Localization

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.

Auth and sessions

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.

Release operations

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);
Automation

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.

Checklist

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.

SDK setup · Project Auth · Headless CMS overview

Now available

Start building with Noma

Create a free account, spin up a project, and ship structured content with our API, SDK, and AI tools.