A Flutter package to improve SEO for Flutter Web applications by dynamically updating the HTML document head (title and meta tags) based on navigation events.
- Dynamic Title Updates: Change the browser tab title as users navigate through your app.
- Meta Tag Injection: Add imperative SEO meta tags (description, keywords, Open Graph, etc.) for each route.
- Automatic Navigation Integration: Easily hook into Flutter's
Navigatorto trigger updates automatically. - Cross-Platform Safety: Safely runs on non-web platforms (no-ops) so you don't need separate code paths.
-
Add
seo_friendlyto yourpubspec.yaml:dependencies: seo_friendly: ^1.0.0
-
Import the package:
import 'package:seo_friendly/seo_friendly.dart';
Create a seo_config.yaml file in your assets folder (and declare it in pubspec.yaml). This file maps route names to their SEO metadata.
# pubspec.yaml
flutter:
assets:
- assets/seo_config.yaml# assets/seo_config.yaml
DEFAULT:
title: "My Amazing App"
meta:
description: "The best app for doing things."
/:
title: "Home | My Amazing App"
meta:
description: "Welcome to the home page."
keywords: "home, main, start"
/about:
title: "About Us | My Amazing App"
meta:
description: "Learn more about our team."Add SeoRouteObserver (or call seoRunner manually) in your MaterialApp.
You can simple call seoRunner(forUrl: routeName) in your own NavigatorObserver or anywhere you handle routing updates.
import 'package:flutter/material.dart';
import 'package:seo_friendly/seo_friendly.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomeScreen(),
'/about': (context) => AboutScreen(),
},
navigatorObservers: [
// You can create a simple observer to trigger updates
MySeoObserver(),
],
);
}
}
class MySeoObserver extends NavigatorObserver {
@override
void didPush(Route route, Route? previousRoute) {
super.didPush(route, previousRoute);
// basic example using route name
if (route.settings.name != null) {
seoRunner(forUrl: route.settings.name!);
}
}
// Implement didPop, didReplace, etc. as needed
}This package uses package:web to manipulate the DOM on web platforms. On other platforms (Android, iOS, etc.), the seoRunner function is a safe no-op.