Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deep link to specific screen in react-native expo

I am creating a link URL with the following code:

Linking.makeUrl('lobby/', {
  roomId: params.roomId
})

which outputs the following: exp://192.168.0.31:19000/--/lobby/?roomId=1585512451

This works fine locally but only seems to open to the Home page of my app.

I have defined the screens in My app.js

const Stack = createStackNavigator();

function App() {  
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen 
          name="Home" 
          component={HomeScreen} 
        />
        <Stack.Screen 
          name="Lobby"
          component={LobbyScreen} 
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Do I need to redirect to the lobby screen with some sort of even listener or should the path passed into makeUrl map to a screen?

like image 314
Stretch0 Avatar asked Mar 29 '20 20:03

Stretch0


1 Answers

Yes you need to listen for the url events. See the section in the Expo documentation on deep linking. https://docs.expo.io/versions/latest/workflow/linking/#handling-links-into-your-app

Note there are additional configuration options you will need in the expo configuration for this to work on different devices. See their documentation for all instructions in that regard.

Quoted from the link provided

Handling links into your app
There are two ways to handle URLs that open your app.

1. If the app is already open, the app is foregrounded and a Linking event is fired
You can handle these events with Linking.addEventListener('url', callback).

2. If the app is not already open, it is opened and the url is passed in as the initialURL
You can handle these events with Linking.getInitialURL -- it returns a Promise that resolves to the url, if there is one.

From their example code:

let redirectUrl = Linking.makeUrl('path/into/app', { hello: 'world', goodbye: 'now' });

Then you need to handle the URL using an event handler

_handleUrl = url => {
  this.setState({ url });
  let { path, queryParams } = Linking.parse(url);
  alert(`Linked to app with path: ${path} and data: ${JSON.stringify(queryParams)}`);
};

Because the behavior is different if your app is opened and the link is clicked vs the app being closed you need 2 different entry points for handling a link.

Inside you HomeScreen component you could put something like this:

    componentDidMount() {
        // handle an initial url on app opening
        Linking.getInitialURL().then(urlRedirect)
    }

And somewhere in your app, maybe in the app.js place a handler for new urls from inside the app.

function urlRedirect(url) {
    if(!url) return;
    // parse and redirect to new url
    let { path, queryParams } = Linking.parse(url);
    console.log(`Linked to app with path: ${path} and data: ${JSON.stringify(queryParams)}`);
    this.navigation.replace(path, queryParams);
}

// listen for new url events coming from Expo
Linking.addEventListener('url', event => {
    urlRedirect(event.url);
});

like image 55
ug_ Avatar answered Oct 06 '22 08:10

ug_