Url Scheme handling

Deep links are commonly used to navigate to the app from another app, a website, or a push notification. While the QuickBrick framework handles out of the box common use cases (open a screen, play an item, etc...), There are situations where a plugin may have to intercept and handle directly the url used to open the app. This guide explains how you can achieve this for any plugin of any type.

Each applicaster app registers schemes which will open the app. When such a link is opened on a device, the QuickBrick app intercepts the full url, and parses it, to extract the host and the query parameters from the url. As a reminder, here are the different parts of the url:

url: [scheme:]//[user]:[password]@[host]:[port]/[path]?[queryParam1=...&queryParam2=...]#fragment

The app will then look for url scheme handlers who can respond to the provided value of host. Currently, all the use cases covered by the app are using the present host

app-scheme://present?...

if the host isn't present, then the app will look for all plugins which have a urlScheme property on their main export. This property is an object with a host property, containing the host for which the plugin should be used, and a handler property, which is the actual handler for urls matching this host:

// main index.ts of your plugin
import { MyPluginScreen } from "./src";
import { useUrlSchemeHandler } from "./src/handler";
MyPluginScreen.urlScheme: {
host: "my-plugin-screen-host",
handler: useUrlSchemeHandler
};
export default MyPluginScreen;

When the app is invoked with a url like

app-scheme://my-plugin-screen-host?q=..&x=...

it will use the handler from your plugin to resolve the url and decide what action to perform. A common use case is to open the screen plugin, and pass parameters from the url. The handler function is invoked with the full url and the query parameters, and is evaluated as a React hook. Therefore, you can use any other React hook you want, including the ones provided by the QuickBrick framework which allow you to interact with navigations, screens, etc...

// src/handler.ts
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
export function useUrlSchemeHandler({ url, query, onFinish }) {
// we want to navigate to the screen, so we'll need the navigator
const navigator = useNavigation();
// lets pull the data for the screen plugin in the app's layout
const { rivers } = usePickFromState(["rivers"]);
const targetScreen = Object.values(rivers).find(
(river) => river.type === MY_PLUGIN_IDENTIFIER
);
// let's make sure the targetScreen exists, and navigate
// to it, passing the query parameters
if (targetScreen) {
// navigation actions should be invoked in the callback
// of the `onFinish` function
onFinish((done) => {
navigator.push({ ...targetScreen, params: query });
// when your screen is presented, this object will
// be available in `navigator.screenData`
// don't forget to say you're done;
done();
});
}
// if your screen isn't found, it is probably a good idea to
// navigate to home.
onFinish((done) => {
navigator.goHome();
done();
});
}

The code above will:

  • allow the screen plugin to intercept and handle deep links matching a certain my-plugin-screen-host
  • find the data in the app's layout about the screen plugin
  • navigate to that screen and forward parameters found on the deep link
  • navigate do the home screen if the screen plugin data is not found