A Few Good CodersStart a project
Mason Brick

web_app

Mason starter for a Flutter WebView shell, with optional Firebase Remote Config and icon/splash hooks. Includes setup and release-hardening guidance.

Updated , by A Few Good Coders

Published 12 sectionsMason Brick

Read this before generating an app

web_app scaffolds a Flutter application around a website using flutter_inappwebview. It is a starter, not a production-ready security or platform configuration. This guide is based on repository revision 5f554a2, whose brick.yaml declares 0.0.1+1, reviewed on 13 October 2026. The BrickHub page could not be independently retrieved during this review; repository contents are not claimed to be byte-identical to the registry artifact.

The fastest path is to generate without Remote Config or icon automation, get a trusted HTTPS site loading on your target device, and add those features afterward. Only enable Remote Config if you need to change the starting URL without a new app release.

Release blocker in the reviewed template: its WebView unconditionally returns ServerTrustAuthResponseAction.PROCEED for server-trust challenges. Remove that override and retain certificate validation before using the generated app with real users or private data. More hardening steps follow below.

1. Install Mason and generate in a clean folder

Install Flutter and ensure flutter, dart, and mason are on PATH. brick.yaml declares Mason ^0.1.1; the generated pubspec declares Dart >=3.4.3 <4.0.0. Package versions installed by hooks may impose newer toolchain requirements.

Use an empty parent directory, not an existing app root. The post-generation hook runs commands and modifies the generated project. Review the hook before executing third-party generators. The pinned Git workflow below makes this guide reproducible even when registry contents or default branches change; the alternative registry command resolves the registry's available release. Check its version before following source-specific steps.

If mason is not found after activation, add Dart's global executable directory to your shell PATH and reopen the terminal. mason add -g installs the brick globally; mason make creates files in the current output location.

Dart
dart pub global activate mason_cli
mason --version
flutter doctor

# Registry installation (choose this OR the pinned repository installation):
mason add -g web_app

# Repository alternative matching the source reviewed here:
# mason add -g web_app --git-url https://github.com/neel-sharma/web_app --git-ref 5f554a2236364ad7dc5bd488a63812f4244098f9

mkdir my_webview_starter
cd my_webview_starter
mason make web_app

2. Answer the four prompts

Prompt variableRecommended first-run valueMeaning
appNamemy_web_appProject name; use a valid lowercase Dart package name with underscores
urlYour own trusted HTTPS siteInitial URL stored in AppConstants.baseUrl
enableRemoteConfigfalseIf true, adds Firebase dependencies and references generated Firebase options
setupLauncherIconAndSplashfalseIf true, opens a PNG picker and runs icon/splash generators

Although the output directory uses a snake-case transform, the pubspec template uses the raw app name. Avoid spaces, punctuation, and a leading digit. Use a plain URL without credentials, embedded quotes, or sensitive tokens: the value is inserted into Dart source.

There are no declared defaults for these four variables. For automation, provide explicit values and disable the graphical image-picker path. Inspect mason make --help for the CLI version you installed before scripting generation.

Know what the hooks do—and do not do

The post hook runs flutter create . inside the snake-case app directory, adds flutter_inappwebview and lottie, conditionally adds Firebase or icon packages, and finishes with flutter pub get. It uses bash on macOS/Linux and cmd on Windows.

The hook prints command failures but does not throw on a nonzero exit code. A completed Mason command is therefore not proof of a healthy generated app. Read the output and run the verification commands below yourself. Hooks run flutter pub add, so the final dependency solution can differ from the versions originally written in the template; inspect and commit the resulting lockfile.

The hook does not run flutterfire configure, create your Firebase project, publish base_url, validate your website, configure app signing, or make every generated platform compatible with the WebView dependency. It does not use Subversion; SVN is not a prerequisite of the reviewed hook.

3. Inspect the generated files

The brick supplies the WebView screen, constants, entrypoint, animation asset, pubspec, and a test template. flutter create supplies platform scaffolding according to your installed Flutter toolchain and enabled targets. Do not confuse the existence of a platform folder with working runtime support.

The entry widget is App. Inspect the generated test template before running it: it may still contain starter assumptions that no longer match the generated UI. Keep tests that exercise your actual WebView and error states.

Dart
my_web_app/
  lib/
    main.dart
    core/app_constants.dart
    presentation/screens/web_view_screen.dart
    firebase_options.dart  # generated later by FlutterFire, if enabled
  assets/
    loading.json
    logo.png               # only after successful image selection
  pubspec.yaml
  test/widget_test.dart
  android/ ios/ ...         # produced by flutter create

4. Verify the basic app before adding Firebase

From the generated app directory, resolve dependencies, analyze, inspect/fix the generated test, and run on a real supported target. Perform a full rebuild after native dependency or manifest changes.

Confirm the release Android manifest permits Internet access, and use HTTPS with a valid certificate. Do not solve TLS or cleartext errors by weakening trust checks. Apply the platform setup required by your resolved flutter_inappwebview version. For browser builds, iframe embedding restrictions and the website's Content Security Policy can prevent a site from loading; native WebView success does not prove Flutter web support.

Success means the intended site loads, the loader disappears, navigation behaves as expected, and failed/offline requests show a recoverable error—not just that flutter run launched.

Dart
cd my_web_app
flutter pub get
flutter analyze
flutter test
flutter devices
flutter run -d YOUR_DEVICE_ID

5. Optional: connect Firebase Remote Config

When enableRemoteConfig is true, the generated main.dart imports firebase_options.dart, but the brick does not create it. Run FlutterFire from the generated project, select your project and supported platforms, then rebuild.

In Firebase Remote Config, create a string parameter named base_url containing an allowed HTTPS URL, then publish it. The template uses a one-minute fetch timeout and a 60-minute minimum fetch interval, and subscribes to changes to that key.

Do not leave base_url unset. The template calls getString, which can produce an empty string. Its baseUrl ?? AppConstants.baseUrl fallback does not handle an empty string. Add a non-empty default, validate scheme and host, and handle fetch errors before adopting the Remote Config branch.

Also cancel the config subscription in dispose, guard asynchronous UI updates with mounted, and account for the delayed callback when the screen closes. These are host-app improvements required by the reviewed scaffold, not features already supplied by the brick.

Dart
dart pub global activate flutterfire_cli
flutterfire configure
flutter pub get
flutter run -d YOUR_DEVICE_ID

Treat a remote URL as configuration, not authority

Keep a small allowlist of hosts your app is intended to display. Validate both the starting URL and subsequent navigations; use external browser handling for approved off-site links. Do not embed authentication secrets in a URL or Remote Config.

This helper is an application-side addition, not generated code. Use its result before constructing the WebView request. Replace the example host and choose an explicit error screen if even the local fallback is invalid. Allowlisting the initial URL alone does not protect redirects or later navigations.

Dart
Uri? allowedStartUrl(String candidate) {
  final uri = Uri.tryParse(candidate.trim());
  if (uri == null || uri.scheme != 'https' || uri.userInfo.isNotEmpty) {
    return null;
  }
  const allowedHosts = {'www.example.com'};
  return allowedHosts.contains(uri.host.toLowerCase()) ? uri : null;
}

// Apply in your generated screen after a successful/caught fetch:
// final url = allowedStartUrl(remoteValue)
//     ?? allowedStartUrl(AppConstants.baseUrl);
// If url is null, show configuration error UI; do not load arbitrary input.

Optional icon and splash setup

Only the icon/splash path needs the image picker. On macOS/Linux the hook looks for zenity; on Windows it launches a PowerShell Windows Forms picker. These require an interactive desktop environment, so leave the option disabled in headless CI.

The selected PNG is copied to assets/logo.png. If selection is canceled or fails, verify the file exists before running generators: the pubspec may still reference it. The template enables launcher generation for Android and iOS and disables web splash generation; it does not promise icons for every platform.

You can skip the picker entirely, supply a reviewed PNG manually, then configure the resolved icon/splash tools in pubspec.yaml. Review their output and rebuild. Installing Zenity is optional for this feature, not a requirement for a basic scaffold.

Required hardening before release

  1. Remove the unconditional server-trust PROCEED callback. Verify invalid certificates are rejected on the targets you ship; never ship a trust-all workaround.
  2. Add approved-host navigation handling, external-link behavior, and explicit download/file-upload/permission flows according to your product.
  3. Handle initial load errors, HTTP errors, offline state, retry, and empty or invalid Remote Config values. The progress animation alone is not error handling.
  4. Dispose subscriptions and controllers where appropriate, cancel or guard delayed callbacks, and check widget mounting before asynchronous state changes.
  5. Validate authentication, cookies, logout, back navigation, accessibility, keyboard behavior, and permissions on physical devices.
  6. Configure release application IDs, signing, icons, privacy disclosures, store requirements, and dependency updates yourself.
  7. Run analyze/tests and a release-mode smoke test for each supported platform. Check the website can legally and technically be embedded.

The documentation exposes these gaps so you can assess the starter honestly. It does not change the upstream brick or automatically repair apps generated from it.

Troubleshooting by symptom

SymptomLikely cause and next step
firebase_options.dart missingRemote Config option enabled but FlutterFire configuration not run
Blank view with Remote ConfigEmpty/unpublished base_url, failed fetch, invalid URL, or unsupported platform listener; add safe defaults/error handling
Loader never disappearsFailed load or network request; implement explicit error/retry handling instead of relying only on progress
Icon generation failsPicker canceled, missing Zenity/desktop session, absent PNG, or generator configuration mismatch
Mason finishes but build failsPost hook logs failures without aborting; inspect each command and rerun pub get/analyze
Website works natively but not in a browserEmbedding/CSP restrictions or platform support differences in the resolved WebView plugin
setState after disposeDelayed config callback or stream callback outlives the screen; guard and cancel

When reporting a problem, include brick revision, Mason/Flutter versions, selected prompt values without private URLs, target device, and the first failed command or runtime error. Do not include Firebase credentials.

Reviewed source and registry link

Repository snapshot: 5f554a2 (opens in a new tab). Review brick.yaml (opens in a new tab), the generation hooks (opens in a new tab), and generated templates (opens in a new tab) before customization.

BrickHub 0.0.1+1 (opens in a new tab) is the registry entry; availability and archive parity were not independently verified in this review. The pinned Git installation above deliberately targets the code examined here.