Migration to Flutter Guide
Discover our battle-tested 21-step framework for a smooth and successful migration to Flutter!
Home
Glossary

Deep linking in Flutter

What is deep linking in Flutter?

Deep linking in Flutter allows opening a specific screen in your app directly from a URL instead of always starting from the home screen.

A deep link can navigate users straight to content like a product, article, or profile.

Why does deep linking matter in Flutter app development?

Deep linking is critical for:

  • push notifications
  • marketing campaigns and ads
  • sharing content between users
  • restoring navigation state after app termination

Without deep links, users always land on the home screen, breaking real-world flows.

How does deep linking work?

Deep linking has two separate layers, both required:

  1. System-level configuration (Android / iOS)
    The operating system must know that certain URLs belong to your app.
    This involves Android: AndroidManifest.xml + App Links and iOS: Info.plist + Universal Links
  2. Flutter routing logic
    Once the app receives the link, Flutter decides which screen to show.
    This is typically handled by routers like GoRouter or auto_route.

Flutter does not receive links automatically — the OS must pass them first.

Flutter deep linking example

With GoRouter, deep linking usually works by:

  • Defining routes with path parameters (e.g. /product/:id).
  • Reading parameters from the incoming URL.
  • Navigating to the matching screen on app start.

The router handles navigation, not the system integration.

When to use deep linking?

Deep linking is essential when your Flutter application needs to connect external sources with internal screens in a reliable and predictable way. It is particularly valuable if your app publishes content that should be discoverable, shareable, or indexed, such as articles, products, or user profiles. Deep links allow users to navigate directly to a specific piece of content from emails, web pages, or QR codes, skipping intermediate screens and improving the user experience.

They are also critical when notifications need to open specific screens, for example, a chat message notification that should jump directly into the conversation, or a promotional alert leading to a particular product page. Deep linking can integrate with analytics and marketing workflows, enabling measurement of user engagement and conversion paths. Additionally, apps that support multiple platforms — iOS, Android, or web — benefit from deep linking as it unifies navigation patterns across entry points, ensuring consistent behavior regardless of how the user launches the app.

When not to use deep linking?

Deep linking introduces additional complexity and is not necessary in every project. Avoid it if the app does not have external entry points, meaning all interactions start from within the app itself. It is also less relevant when navigation is very simple, for instance, a single-screen utility or tool where deep linking adds overhead without practical benefits.

Apps that work entirely offline or where content cannot be dynamically addressed do not gain value from deep linking, as users cannot follow external links into specific content. Implementing deep linking in such cases can create unnecessary boilerplate and testing overhead, as well as potential edge-case bugs related to URL handling or app state restoration.

Deferred deep linking in Flutter

Deferred deep linking means:

  1. The user opens a link.
  2. The app is not installed.
  3. After installation, the app still receives the original link.

Flutter does not support this natively.

Recommended third-party solutions include:

  • Branch.io
  • AppsFlyer
  • Adjust

Firebase Dynamic Links should no longer be used — the service is deprecated and scheduled for shutdown.

Custom schemes (myapp://) are easy to set up but unreliable:

  • Browsers often treat them as search queries.
  • They do not work consistently across platforms.

Universal Links (iOS) and App Links (Android) are the recommended approach for production apps.

Critical system configuration detail

For App Links and Universal Links, app configuration alone is not enough.

You must also host verification files on your domain:

  • Android: assetlinks.json
  • iOS: apple-app-site-association

Without these files, the OS will ignore your links even if the app is configured correctly.

Common mistakes when implementing deep linking in Flutter

  • Testing only hot restart instead of cold start.
  • Forgetting server-side verification files.
  • Assuming routers enable deep linking automatically.
  • Relying on custom schemes for browser-based links.

Best practices for deep linking in Flutter

  • Always test links with the app fully terminated.
  • Prefer Universal Links and App Links over custom schemes.
  • Handle unknown URLs gracefully.
  • Log incoming links during development.

Deep linking in Flutter is not just routing — it is a system-level integration that must be implemented end to end.

Learn more

Sharing Logic Across Multiple Platforms - Solution by LeanCode

Sharing Logic Across Multiple Platforms

When a project grows, sooner or later, a need for sharing logic across multiple clients and a server arises. At LeanCode, we completed a project that extensively employed logic sharing successfully. In this article, we highlight the steps and architecture decisions of the picked solution.

Flutter architecture by LeanCode

Feature-Based Flutter App Architecture - LeanCode

Read about the LeanCode approach to Flutter architecture. We highlight some of the design decisions that should be made when developing a feature in mobile apps. This includes our approach to dependency injection, state management, widget lifecycle, and data fetching.