Skip to main content

Navigation and links

Take your users straight to a community screen from anywhere in your app, and decide which links the community opens itself.

Before you begin​

How it works​

By default, the community opens on its main feed. You can open it on another screen instead, in one of two ways:

ModeWhat the user seesBack or close returns to
Community contextThe screen, inside the full community navigationThe community main feed
IsolationThe screen alone, without the main feed behind itYour app

Community context is available on Android, where the community screens live in your own navigation graph. Every platform can open a screen in isolation.


Open a specific screen​

Each platform has one entry point per mode. The sections below then show each screen in the same order: a post, a group, a member, and the post editor.

Open in the community context​

Android availableiOS not availableFlutter not availableReact Native not availableUnity not available

The screen is pushed on your navigation stack, on top of the community graph. The user can navigate back to the main feed.

Register the community graph with octopusComposables in your NavHost (see Display the community), then call a navigateToOctopus… extension on your NavHostController:

ScreenCall
Main feednavigateToOctopusHome()
PostnavigateToOctopusPost(postId)
GroupnavigateToOctopusGroup(groupId)
Member activitynavigateToOctopusActivity(userId) or navigateToOctopusActivityByClientUserId(clientUserId)
Member profilenavigateToOctopusProfile(userId) or navigateToOctopusProfileByClientUserId(clientUserId)
Post editornavigateToOctopusCreatePost(info)
navController.navigateToOctopusPost(postId = "YOUR_POST_ID")

Open a screen in isolation​

The screen opens alone. Its back arrow, close button or system back gesture returns the user to your app.

Show a dedicated screen composable. It does not need the community graph.

ScreenComposable
PostOctopusPostDetailsScreen(navController, postId)
GroupOctopusGroupDetailsScreen(navController, groupId)
Post editorOctopusCreatePostScreen(navController, info)

OctopusPostDetailsContent and OctopusGroupDetailsContent are the same screens with navigation callbacks: login, profile edit, URL handling and profile taps. Use them when your users sign in with your own account system.

Open a post​

// In the community context
navController.navigateToOctopusPost(postId = "YOUR_POST_ID")

// In isolation, as a destination of your own NavHost
OctopusPostDetailsScreen(
navController = navController,
postId = "YOUR_POST_ID",
)

Open a group​

// In the community context
navController.navigateToOctopusGroup(groupId = "YOUR_GROUP_ID")

// In isolation, as a destination of your own NavHost
OctopusGroupDetailsScreen(
navController = navController,
groupId = "YOUR_GROUP_ID",
)

Open a member's activity or profile​

A member's activity screen lists their posts, and their comments when the community exposes them. Identify the member with your own user id or with their Octopus profile id. The full options are in Open a member's activity screen directly and Open a member's profile screen directly.

≥ 1.13.0
navController.navigateToOctopusActivityByClientUserId(clientUserId = "YOUR_USER_ID")

Open the post editor​

The post editor can open empty, or prefilled with content from your app: text, an image, a target group and a call-to-action (CTA). This is how a Bridge Share starts. Every field is optional. The user can edit the text, the image and the group before publishing. The CTA is not shown in the editor: it is attached to the published post.

Rules shared by every platform:

  • Text, when present, is 10 to 5000 characters long.
  • The image is local data. The SDK never downloads a remote URL.
  • A missing or inaccessible group makes the user pick one before publishing.
  • A CTA needs both a URL and a label.

To publish a prefilled image in a community that forbids member pictures, sign it on your backend: see Bridge share image signing.

Parameters of OctopusPrefilledPost:

  • text (String?): initial text.
  • image (Uri?): local content URI of an image. If the URI comes from PickVisualMedia, call contentResolver.takePersistableUriPermission(...) first, so it survives process death.
  • topicId (String?): id of the target group.
  • cta (OctopusPostCTA?): the call-to-action.

Blank values become null. The constructor throws an OctopusPrefilledPost.ValidationError, an IllegalArgumentException: TextTooShort, TextTooLong, CtaLabelEmpty or CtaUrlEmpty. The editor checks the image dimensions when it opens.

import androidx.core.net.toUri
import com.octopuscommunity.sdk.domain.model.CreatePostScreenInfo
import com.octopuscommunity.sdk.domain.model.OctopusPostCTA
import com.octopuscommunity.sdk.domain.model.OctopusPrefilledPost
import com.octopuscommunity.sdk.ui.navigateToOctopusCreatePost

try {
val prefill = OctopusPrefilledPost(
text = "The perfect Canelés",
image = recipeImageUri,
topicId = recipeGroupId, // null lets the user pick a group
cta = OctopusPostCTA(
url = "https://www.example.com/recipes/caneles".toUri(),
label = "Read the recipe",
),
)
navController.navigateToOctopusCreatePost(
info = CreatePostScreenInfo(prefilledPost = prefill),
)
} catch (e: OctopusPrefilledPost.ValidationError) {
// Show your own error; the editor did not open
}

In isolation, pass the same info to OctopusCreatePostScreen(navController, info). CreatePostScreenInfo() opens an empty editor.


Intercept URL openings​

Members open links from post, comment and reply content, and from CTA buttons. By default, the SDK opens them itself. Intercept them to open some links in your own app instead, for example a page of your website that your app also shows.

Your handler receives the URL and returns a strategy:

StrategyEffect
Handled by appYour app handled the URL. The SDK does nothing more.
Handled by OctopusThe SDK opens the URL.

Pass onNavigateToUrl to octopusComposables, and to OctopusHomeContent or the …Content screens you use.

import androidx.core.net.toUri
import com.octopuscommunity.sdk.ui.UrlOpeningStrategy

octopusComposables(
navController = navController,
onNavigateToUrl = { url ->
val uri = url.toUri()
if (uri.host == "www.example.com" && uri.path == "/contact") {
navController.navigate(ContactRoute)
UrlOpeningStrategy.HandledByApp
} else {
UrlOpeningStrategy.HandledByOctopus
}
},
)

See the UrlHandler of the Android sample.

info

≥ 1.13.2 With HandledByOctopus, the SDK opens the link in a Chrome Custom Tab colored from the SDK palette, including the one you install through the theming container of octopusComposables. The tab takes light or dark from that palette when it opens, not from the device setting: an open tab does not follow a system dark mode change. Transparent colors are not forwarded to Chrome, which uses its own default for them.

Next steps​