Dio Flutter

Build Your Portfolio Website Using Flutter Web and Dio

๐Ÿš€ Build Your Portfolio Website Using Flutter Web and Dio

In todayโ€™s world, having a strong digital presence is essentialโ€”especially if youโ€™re a developer or freelancer. One of the best ways to showcase your skills is through a personal portfolio website. And now, with Flutter Web, you can create beautiful, cross-platform portfolio websites using just one codebase.

In this guide, youโ€™ll learn how to build a modern, mobile-friendly portfolio site using Flutter Web, enhanced with Dio to handle contact form submissions.

๐Ÿ“ฆ What is Dio?

Dio is a powerful HTTP client for Dart, widely used in Flutter apps. It offers features like interceptors, global configuration, form handling, and more. In this project, weโ€™ll use it to submit contact forms directly to an API.

Install Dio:

dependencies:
  dio: ^5.4.0

๐Ÿ› ๏ธ Project Overview

The portfolio will contain the following sections:

  • About Me
  • My Skills
  • My Portfolio
  • Contact Us

๐Ÿ’ก Set Up the Project

flutter create portfolio_web
cd portfolio_web
flutter run -d chrome

๐Ÿ–ผ๏ธ Create the Screens

Create separate Dart files in your screens/ folder for each section.

1. About Me

class AboutMe extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(\"Hi, I'm a Flutter Developer passionate about clean UI.\"),
    );
  }
}

2. My Skills

final skills = ['Flutter', 'Dart', 'Firebase', 'Dio'];

ListView.builder(
  itemCount: skills.length,
  itemBuilder: (context, index) => ListTile(
    leading: Icon(Icons.check),
    title: Text(skills[index]),
  ),
);

3. Portfolio

final projects = [
  {'title': 'To-Do App', 'description': 'A task manager with cloud sync'},
];

ListView.builder(
  itemCount: projects.length,
  itemBuilder: (context, index) => ListTile(
    title: Text(projects[index]['title']!),
    subtitle: Text(projects[index]['description']!),
  ),
);

4. Contact Us (with Dio)

final dio = Dio();
final nameController = TextEditingController();

ElevatedButton(
  onPressed: () async {
    await dio.post('https://your-api.com/contact', data: {
      'name': nameController.text,
      'email': emailController.text,
      'message': messageController.text,
    });
  },
  child: Text('Submit'),
);

๐ŸŒ Deploy Your Website

flutter build web

This command generates the website in the /build/web folder. You can host it using:

  • GitHub Pages
  • Firebase Hosting
  • Netlify / Vercel

๐Ÿš€ How to Use Dio Interceptors in Your Flutter Web Portfolio

Dio is one of the most powerful HTTP clients for Flutter. But did you know you can add an Interceptor to log, modify, or handle API requests globally? ๐Ÿ˜Ž In this quick guide, youโ€™ll learn how to use InterceptorsWrapper with Dio in your Flutter Web portfolio project.

๐Ÿ›ก๏ธ What is an Interceptor?

An interceptor acts like a watchman on your network calls. It can:

  • Log API requests and responses
  • Attach tokens to headers
  • Handle errors like 401/500 globally
  • Retry failed requests

๐Ÿ”ง How to Add an Interceptor in Dio

Hereโ€™s how to add it to your app:


// 1. Import Dio
import 'package:dio/dio.dart';

// 2. Create Dio instance and add Interceptor
final dio = Dio();

dio.interceptors.add(
  InterceptorsWrapper(
    onRequest: (options, handler) {
      print('๐Ÿ‘‰ Request: \${options.method} \${options.path}');
      options.headers['Authorization'] = 'Bearer YOUR_TOKEN_HERE';
      return handler.next(options);
    },
    onResponse: (response, handler) {
      print('โœ… Response: \${response.statusCode}');
      return handler.next(response);
    },
    onError: (DioError e, handler) {
      print('โŒ Error: \${e.message}');
      return handler.next(e);
    },
  ),
);
  

๐Ÿ“ฉ Example: Use Interceptor in Contact Form

This example hooks into your “Contact Us” form to log the submission.


ElevatedButton(
  onPressed: () async {
    try {
      final response = await dio.post(
        'https://your-api.com/contact',
        data: {
          'name': nameController.text,
          'email': emailController.text,
          'message': messageController.text,
        },
      );
      print("โœ… Message sent: \${response.statusCode}");
    } catch (e) {
      print("โŒ Error occurred: \$e");
    }
  },
  child: Text('Submit'),
);
  

๐Ÿ”ฅ What Can You Do with Interceptors?

  • Add headers โ†’ Add auth tokens globally
  • Log API calls โ†’ Great for debugging
  • Catch errors โ†’ Show a snackbar or redirect
  • Retry logic โ†’ Handle network drops

โœ… Summary

  • Tool: Dio + InterceptorsWrapper
  • Use: Monitor, modify, handle all API calls
  • Power: Centralized token + error management

๐ŸŽฏ Add this to your Flutter Web portfolio site to make your backend integration rock solid! Got questions? Drop them in the comments below ๐Ÿ‘‡

Full Code

๐Ÿš€ Build a Contact Form with Dio Interceptor in Flutter Web

Want to take your Flutter Web portfolio to the next level? In this tutorial, you’ll learn how to integrate a contact form with Dio, use interceptors for request/response handling, and send data to an API.

๐Ÿ“ฆ What is Dio?

Dio is a powerful HTTP client for Flutter/Dart. It supports interceptors, global configuration, and error handling. We’ll use it to submit a contact form and log API requests using an interceptor.

๐Ÿง  What is an Interceptor?

  • Intercepts every API request and response
  • Can log, modify headers, and handle errors globally
  • Great for adding tokens or showing messages on failures

๐Ÿ› ๏ธ Full Flutter Web Example with Interceptor

This is your complete main.dart file that builds a portfolio contact page with Dio:


import 'package:flutter/material.dart';
import 'package:dio/dio.dart';

void main() {
  runApp(MyPortfolioApp());
}

class MyPortfolioApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My Flutter Web Portfolio',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: PortfolioHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class PortfolioHomePage extends StatelessWidget {
  final Dio dio = Dio();
  final TextEditingController nameController = TextEditingController();
  final TextEditingController emailController = TextEditingController();
  final TextEditingController messageController = TextEditingController();

  PortfolioHomePage() {
    dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (options, handler) {
          print("๐Ÿ“ค Sending Request to: ${options.uri}");
          options.headers['Authorization'] = 'Bearer demoToken123';
          return handler.next(options);
        },
        onResponse: (response, handler) {
          print("โœ… Response: ${response.statusCode}");
          return handler.next(response);
        },
        onError: (DioError e, handler) {
          print("โŒ Error: ${e.message}");
          return handler.next(e);
        },
      ),
    );
  }

  void sendContactForm(BuildContext context) async {
    try {
      final response = await dio.post(
        'https://your-api.com/contact',
        data: {
          'name': nameController.text,
          'email': emailController.text,
          'message': messageController.text,
        },
      );
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("Message Sent! Status: ${response.statusCode}")),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("Error sending message")),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("๐Ÿง‘โ€๐Ÿ’ป My Portfolio")),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("๐Ÿ‘‹ About Me", style: Theme.of(context).textTheme.headline5),
            SizedBox(height: 10),
            Text("Hi! I'm a Flutter Developer passionate about UI and Web.",
              style: TextStyle(fontSize: 16)),
            Divider(height: 40),

            Text("๐Ÿ“จ Contact Me", style: Theme.of(context).textTheme.headline5),
            SizedBox(height: 10),
            TextField(controller: nameController, decoration: InputDecoration(labelText: 'Name')),
            TextField(controller: emailController, decoration: InputDecoration(labelText: 'Email')),
            TextField(controller: messageController, maxLines: 4, decoration: InputDecoration(labelText: 'Message')),
            SizedBox(height: 20),
            ElevatedButton.icon(
              onPressed: () => sendContactForm(context),
              icon: Icon(Icons.send),
              label: Text("Submit"),
            ),
          ],
        ),
      ),
    );
  }
}
  

๐Ÿงช How to Test This

  • Run on Chrome: flutter run -d chrome
  • Replace API URL with: https://httpbin.org/post for testing
  • Watch console logs for request/response

โœ… Summary

  • ๐Ÿ“ฌ Dio handles form submissions
  • ๐Ÿ” Interceptors let you log, attach headers, and manage errors
  • ๐ŸŒ Flutter Web gives you a beautiful front-end for all of this

Let me know if you want the ZIP download, retry logic, or a fancier UI in the comments!

Leave a Reply

Your email address will not be published. Required fields are marked *