How to deep link to specific screen in react-native expo
Asked Answered
N

1

10

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?

Naamana answered 29/3, 2020 at 20:12 Comment(0)
A
9

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);
});

Acquirement answered 29/3, 2020 at 20:39 Comment(2)
not possible to add navigation in app.js. TypeError: undefined is not an object (evaluating '_this3.props.navigation.replace')Interdiction
I am using react navigation with authentication flow and implement deep link in expo managed workflow react native app. I am try to open nested screen using deep link but not working as open home screen first than open actual deep link screenMenchaca

© 2022 - 2024 — McMap. All rights reserved.