When building websites with Flutter, a significant challenge encountered is Search Engine Optimization (SEO). The main issue arises because search engine crawlers often fail to index the text content in Flutter web applications. This limitation stems from the fact that Flutter web builds essentially result in static websites, which aren't crawler-friendly by default.
Addressing this challenge with Flutter alone is a daunting task. Given the nature of static sites produced by Flutter web builds, incorporating an additional web project, like one built with Next.js, becomes essential. This approach is not only about solving crawling issues but also about dynamically providing appropriate meta tags based on the content, which is nearly impossible with just Flutter.
Rather than struggling with these limitations, a practical solution involves embedding your Flutter web site within a server-side rendering project like Next.js. This method allows for significant improvements in SEO. For instance, you can detect web crawlers and return suitable meta tags accordingly. Similarly, for content within your Flutter web that needs to be exposed to crawlers, presenting a slimmed-down HTML version without CSS proves to be highly effective.
-
Create a Next.js Project: First, set up a new Next.js project if you don't have one already.
npx create-next-app my-nextjs-project cd my-nextjs-project
-
Include Your Flutter Web Project: Place your built Flutter web project in the
public
directory of your Next.js project.my-nextjs-project/ ├── public/ │ └── flutter_web_project/ # Your Flutter web build files └── ...
-
Server-Side Rendering with Next.js: In your Next.js pages, use server-side rendering to detect crawlers and modify meta tags dynamically. Here's an example of a basic setup:
import { useEffect } from 'react'; const Home = ({ isCrawler }) => { useEffect(() => { if (!isCrawler) { // Load Flutter web app for regular users window.location.href = '/flutter_web_project/index.html'; } }, [isCrawler]); return ( <div> {isCrawler ? ( // Provide SEO-friendly content for crawlers <div> <h1>My Flutter Web App</h1> <p>Here's some content that's important for SEO...</p> {/* More SEO-friendly content */} </div> ) : ( // Regular users will be redirected to Flutter web app <p>Loading...</p> )} </div> ); }; export async function getServerSideProps(context) { const userAgent = context.req.headers['user-agent']; const isCrawler = /bot|googlebot|crawler|spider|robot|crawling/i.test(userAgent); return { props: { isCrawler } }; } export default Home;
Integrating a Flutter web project into a server-side rendered framework like Next.js not only resolves crawling issues but also opens up the door for dynamic meta tag management and better overall SEO performance. This approach leverages the strengths of both technologies, offering a more comprehensive solution for web development.
To implement this integration successfully, it's essential to modify the URL strategy in your Flutter web project. By default, Flutter uses hash (#
) in the URLs, which can be problematic for SEO. To enhance the SEO, you should switch to using the 'path' URL strategy that doesn't include the hash.
You can change this in your Flutter web project by utilizing the url_strategy
package. Here’s how to set it up:
-
Add the
url_strategy
package to yourpubspec.yaml
file:dependencies: url_strategy: ^0.2.0
-
Set the URL strategy to 'path' in your main.dart:
import 'package:url_strategy/url_strategy.dart'; void main() { setPathUrlStrategy(); // Use path-based URLs instead of hash-based runApp(MyApp()); }
By doing this, your Flutter web URLs will be cleaner and more SEO-friendly, which is crucial for better indexing by search engines.
I have to say this is a great approach to overcome the SEO issue with Flutter Web. I am currently also trying around to get some basic SEO done with Flutter Web. I also have tried your approach on an own project. I am figuring out the step 2 of your guide. Do you mean by "build web files" the /web folder in the build folder of my flutter project? If I only add this I only see an infinite loading screen and nothing is happening. It doesn't find the manifest.json (even if it is in the folder) and the flutter.js is not loading properly probably because some files are missing.
Could you tell me a bit more which files I need to copy inside the Next.js folder in order to execute the project successfully?