You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3.9 KiB


A starter to bootstrap the creation of Apps synced with a directus API the project must stay deployable on Android / IOS / WEB / WIN Use GetX for state management, routing and translating

Before runing the project be sure to set apiUrl in /lib/globals.dart

run this project with flutter -v run -d *chrome* --web-port=8085

With VSCode

Create a launch.json file in *root*/.vscode/ :

  "version": "0.2.0",
  "configurations": [

      "name": "Flutter",
      "request": "launch",
      "type": "dart",
      "args": ["-d", "chrome","--web-port", "8085"],


"@" is shorthand for project_dir/lib

  • @/views/ app screens
  • @/components/ widgets used in view
  • @/store state providers
  • @/template reusables layouts
  • @/lang translations files

State Management

State Management is done with Getx ( GetX doc )

All the data is persisted online throught a Directus API ( Directus doc )

Create a controller:

for a directus collection named car simply add a file carsController.dart in @/store :

// @/store/carsController.dart
import 'package:directus_starter/store/itemsController.dart';

class CarsController extends ItemsController {
      : super("project", fields: ['*']) {

Display the data:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:directus_starter/store/carsController.dart';

class CarDemo extends StatelessWidget{

  //make the carsController accessible
  final CarsController carsController = Get.put(carsController());

  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(...),
      body: Center(
        child: Obx( () => Text(carsController.items[0]["model"]) )

carsController.items return a Map<String, dynamic> that you can use in a ListView.builder

see @/views/project.dart for a real world example

Controller Helpers

//getter itemsMppedOnId
Map<String ,dynamic> {
    'id': 'car1',
    'model': 'Model X',
    'brand': 'Tesla'
    'id': 'car2',
    'model': 'Model 3',
    'brand': 'Tesla'
    'id': 'car3',
    'model': 'Model S',
    'brand': 'Tesla'

// imagin you have user that has a relation with a car, the userController will give you the car id so you can access the car entity with: 

var carIdOfUser = 'car1';

// with function getItemById()

// with function getItemsByIds()
// if user has multiple cars and relation is a one(user) to many(cars)
carController.getItemsByIds(['car1', 'car2' ,'car3']);

Modify the data

///# add a car

var newCar = {
  'model': 'Model XXX',
  'brand': 'Tesla'
// newCar MUST NOT contains an 'id' field, it will be generated by the API

// return false if the api reject the new car

///# Modify a car
var updatedCar = {
  'id': carController.item[0].id,
  'brand': 'Hummer',
//updatedCar MUST contains the id of the item to update
// return false if the api reject the updated car

///# delete a car
//pass only the id of the item to delere
// return false if the api refuse to delete the car


language files are located in @/lang/ locals default values are stored in @/globals.dart then these values are feeded into the getMaterialApp call in @/main.dart


use Text('key'.tr); in any widget to get the translated text

change local:

var locale = Locale('en', 'US');

get system local:

return GetMaterialApp(
  locale: Get.deviceLocale,