Hey <@U0234N0QYSK> :wave::skin-tone-2:, I’ve been ...
# compose-destinations
i
Hey @Rafael Costa 👋🏻, I’ve been exploring an idea for improving support for multi-module shared/reusable destinations, and I wanted to share it here to get your thoughts. I'll put it in a Thread.
Currently, the
@Destination
annotation can be applied multiple times to include a screen in multiple NavGraphs (as described here). This would generate multiple destinations with a prefix of the NavGraph. However, this only works well in single-module apps — in multi-module projects, the module that defines a shared screen doesn’t know about other modules or NavGraphs. For multi-module setups, we therefore have the
@ExternalModuleGraph
and
@ExternalDestination<T>
mechanism, which lets one module import a destination defined in another. The destination cannot be used unless imported in a specific NavGraph. The limitation is that because each route must be unique, a destination can only be imported into one NavGraph. I want to prevent having just a
Composable
in a shared module and defining a destination in each module where you need the screen, using the shared
Composable
as content. I’d like to repurpose the
@ExternalModuleGraph
. The idea is that this annotation marks a destination as a “stub-only” destination, meaning the module that defines the destination only generates a stub (not a full destination). Then, other modules could import that stub (e.g.
@ExternalDestination<FeedbackScreenDestinationStub>
), and the real destinations would be generated in the importing modules as if it were defined there. Making them reusable destinations. That way: • Each NavGraph that includes the stub would get its own properly namespaced destination: ◦
DocumentFeedbackScreenDestination
in
DocumentNavGraph
◦
ProfileFeedbackScreenDestination
in
ProfileNavGraph
• Routes would be unique per NavGraph (following the graph’s prefix as is done for single-module destinations currently). • This would also improve nested graph imports, like using
@ExternalNavGraph<PaymentNavGraph>
inside
CheckoutNavGraph
, where generated routes would become
CheckoutPaymentComfirmationScreenDestination
instead of
PaymentConfirmationScreenDestination
. • For the top-level NavGraphs such as
@NavHostGraph
, we could exclude this behaviour to prevent over-nesting. This would make shared flows (like feedback or payment) much easier to reuse across multiple features while keeping routes unique. Would this kind of feature fit into the project’s roadmap, or do you see a better approach for handling reusable destinations in a multi-module way?
r
Thanks for a detailed proposal like this 👍 Yeah this was, believe it or not, something I considered when developing v2, but ultimately decided that it would bring a bit of complexity with little gains - I mean users can just do Composables like you mentioned and wrap them on each module they need them as Destinations. To me it doesn’t really seem worth the trade off. But yes if you have lets say hundred of modules doing wrappers destinations, I could see the benefit.
i
I agree that it adds some complexity. However, I haven’t found a better way to bring the convenience of multiple destination annotations from a single-module setup into a multi-module project. It would be nice to keep the NavGraph prefix consistent across both types, but I haven’t yet found a clean, low-complexity way to achieve that. It would be nice if the
route
was part of the override parameters, but that means the generated
External_XDestination
external route object would need to define a real destination with a route instead of just a proxy for the original.