madeenan

Flutter Integration Guide

Add Islamic Source Search to a Flutter App

A mobile-safe Flutter pattern using a backend proxy, typed result models, and citation-friendly UI.

What You Will Build

A Flutter search flow that calls your own backend and renders source references, Arabic text, translations, and grades.

Prerequisites

  • Flutter 3
  • The http package
  • A backend proxy with a Madeenan API key

Define a Small Source Model

Mobile UI becomes difficult to maintain when every widget reads directly from an untyped JSON map. Define a small source model at the network boundary, parse the fields the interface uses, and keep source type and reference mandatory. Those two values make both citation rendering and production debugging possible.

Treat Arabic, translation, and grade as optional because not every source family supplies the same shape. The widget should decide how to render a missing optional field; the parser should reject a result that lacks the stable identity or reference the product needs.

For a larger application, add a sealed source type with Quran and Hadith variants. That gives each card access to the metadata it can genuinely support without filling one universal model with nullable fields.

class SourceResult {
final String type;
final String reference;
final String? arabic;
final String? translation;
final String? grade;
SourceResult.fromJson(Map<String, dynamic> json)
: type = json['type'] as String,
reference = json['ref'] as String,
arabic = json['arabic'] as String?,
translation = json['translation'] as String?,
grade = json['grade'] as String?;
}

Send the Query to Your Backend

An API key embedded in an APK or IPA should be treated as public. Obfuscation raises the effort required to extract it; it does not create a security boundary. Send the query to an authenticated backend endpoint and keep the Madeenan credential in that server environment.

The backend should apply user-level rate limits, validate supported indexes, and use a short upstream timeout. Return a stable error code that the Flutter client can translate into useful UI instead of exposing raw provider or network messages.

On the client, separate connection failures from an empty successful response. A user with poor connectivity needs a retry action. A user whose query produced no source matches needs help refining the phrase.

final response = await http.post(
Uri.parse('$backendBaseUrl/islamic-search'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'query': query}),
);
if (response.statusCode != 200) {
throw const SourceSearchException();
}

Render Right-to-Left Text Deliberately

Arabic and English should not compete inside one text block. Render Arabic with TextDirection.rtl and the app’s Quran-capable font, then place the translation in a separate widget using the interface direction. This keeps punctuation, wrapping, and selection behavior predictable.

Let the card grow vertically. Fixed-height source cards often look tidy at the default font size and fail as soon as Arabic wraps or the user enables larger accessibility text. Constrain line length with padding, not a hard container height.

Test a long Quran passage, a short Hadith, a missing translation, and 200% text scaling on a narrow device. Also verify that the reference remains visible before the excerpt, since users should not need to scroll through the entire card to learn what they are reading.

Security Boundary

Secrets extracted from a mobile package are compromised secrets. Authenticate users to your backend and keep the Madeenan key there.

Test Before Shipping

  • Search an exact Quran reference
  • Search a Hadith topic
  • Test right-to-left Arabic
  • Test 200% text scaling
  • Verify the APK or IPA does not contain the API key