The purpose of this application is to create a dashboard where you can share the books you have read, future books, and track the progress of those being read.
The application currently allows you to view books that have been saved in a Supabase database and shows them on a web page, so it does not allow books to be added, edited or deleted.
A Supabase database with these characteristics was used to save the list of books and their characteristics:
CREATE TABLE public.books (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
created_at timestamp with time zone NOT NULL DEFAULT now(),
title character varying NOT NULL DEFAULT ''::character varying,
author character varying NOT NULL DEFAULT ''::character varying,
progressive_page integer NOT NULL,
total_pages integer NOT NULL,
finished_date date,
cover character varying NOT NULL DEFAULT ''::character varying,
link character varying NOT NULL,
finished boolean NOT NULL DEFAULT false,
CONSTRAINT books_pkey PRIMARY KEY (id)
);In order to have a complete environment that allows me, with each push on main, to have an automatic deployment in production I relied on Netlify where I created a new site and configured in their dashboard the domain to which the build responds, had Netlify generate an SSL certificate with Let's Encrypt to have my site available under https, created the environment variables and set up the file that it has to read to run the build whose code is in the file netlify.toml.
Netlify already provides an integration for building a Flutter web app with the Flutter SDK plugin that you can install with a single click on your site, the project repo can be found here: Netlify Flutter Build Plugin.
With all this configured each push on main automatically triggers a build that if correct that is released directly to production within a few minutes.
I used freezed to handle the json responses coming back from the API, but the generated *.freezed.dart and *.g.dart files were not committed, so before starting the project you need to run build_runner in order to create them:
dart run build_runner build --delete-conflicting-outputsTo run the project you have to pass some environment variables as described here: How to Store API Keys in Flutter: --dart-define vs .env files, in my case I opted for passing the key using --dart-define as it is easily integrated with CI/CD tools. This can be done in two ways:
- pass individual variables to the build command with
--dart-define MY_VARIABLE=value, a choice that is later used in Netlify to create the release build - pass a file with the variables with
--dart-define-from-file=api-keys.json, a more convenient choice when developing locally
In the first case the command is:
flutter run --dart-define MY_VARIABLE=valueIn the second case, on the other hand, you have to go and create a file called api-keys.json to put in the root of the project, with this content:
{
"MY_VARIABLE": "value"
}and then pass it like this:
flutter run --dart-define-from-file=api-keys.jsonWithin the app you can then take the reference to the environment variable in this way:
const myEnvironmentValue = String.fromEnvironment('MY_VARIABLE');In my case variables that are passed at build time, and which is also specified in the netlify.toml file are SUPABASE_URL and SUPABASE_ANON_KEY.
If you have any idea, feel free to fork it and submit your changes back to me.
This project is released under the MIT license. You can use the code for any purpose, including commercial projects.


