Could be interesting. Any ideas on how you would you map url elements to props?
https://github.com/reactjs/react-router
React router accepts path param like path="/user/:userId", and you can get userId as such this.props.params.userId.
It could be good enhancement, any PR is welcome.
It should not be difficult to implement - implement additional Actions.path 'action' that will accept path, parse that path and call appropriate action Actions.user({userId:VALUE})
I would love to see this implemented. I have a React app that uses the "react-router" package and need to port its logic to a react-native mobile app. It would be nice if I could just keep the "url-based" routing logic which is already implemented (ok, with some tweaks).
It turned up to be very easy, I just made a simple project on iOS and it worked... writing the steps here for anyone interested:
1- Open the Xcode project, click on the project root, then "Info", add a URL type at the bottom

2- Follow the instructions on Linking page, you have to add the header's search path in Xcode as described here, then copy paste these two methods in your AppDelegate.m to enable your JavaScript receive URL events:
#import "RCTLinkingManager.h"
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
// Only if your app is using [Universal Links](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html).
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
3- npm install --save crossroads Crossroads is a route matching library which does a lot, I guess its too much for simple route matching, but I couldn't find anything simpler... I tried Page first but it didn't work, I guess its intended to work with browser's location only
4- My entry point looks like this:
// index.ios.js
import app from './source/app';
app('ios');
5- My app looks like this... ignore the Redux stuff if you're using something else:
// source/app.js
import React from 'react';
import { AppRegistry } from 'react-native';
import { Provider } from 'react-redux';
import Router from './containers/Router';
import configureStore from './store';
const store = configureStore();
export default function app(platform) {
let Test = React.createClass({
render() {
return (
<Provider store={ store }>
<Router />
</Provider>
);
}
});
AppRegistry.registerComponent('Test', () => Test);
}
6- Finally, the router:
// source/containers/Router/index.js
import React, { Component, PropTypes } from 'react';
import { Linking } from 'react-native';
import { connect } from 'react-redux';
import { Actions, Router, Reducer, Scene } from 'react-native-router-flux';
import crossroads from 'crossroads';
// import some views
import PageOne from '../PageOne';
import PageTwo from '../PageTwo';
import PageThree from '../PageThree';
// define router scenes
const scenes = Actions.create(
<Scene key="root">
<Scene
key="pageOne"
component={ PageOne }
title="One"
initial={ true }
/>
<Scene
key="pageTwo"
component={ PageTwo }
title="Two"
/>
<Scene
key="pageThree"
component={ PageThree }
title="Three"
/>
</Scene>
);
// define URL schemes
crossroads.addRoute('page-one/{id}', Actions.pageOne);
crossroads.addRoute('page-two/{id}', Actions.pageTwo);
crossroads.addRoute('page/:whatever*:', Actions.pageThree);
class Routes extends Component {
static propTypes = {
dispatch: PropTypes.func
};
constructor(props) {
super(props);
this.createReducer = this.createReducer.bind(this);
}
componentDidMount() {
Linking.addEventListener('url', this.handleOpenURL);
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL(event) {
if (event.url && event.url.indexOf('test://') === 0) {
// remove "test://" and try to match
crossroads.parse(event.url.slice(7));
}
}
createReducer(params) {
const defaultReducer = Reducer(params);
return (state, action) => {
this.props.dispatch(action);
return defaultReducer(state, action);
};
}
render() {
return (
<Router
createReducer={ this.createReducer }
scenes={ scenes }
/>
);
}
}
export default connect()(Routes);
7- Open Safari, type "test://page-two/123" and you should be taken to PageTwo
I think given the simplicity and the solution posted here, we should move on from adding to this library. Thoughts?
Totally forgot about this... just wanted to add something to my previous comment, that will only work if app is already in background on iOS, if you want to handle URLs even when the app is closed you should add this to the component
componentDidMount() {
Linking
.getInitialURL()
.then(url => {
this.handleOpenURL({ url });
})
.catch(error => console.error(error));
Linking.addEventListener('url', this.handleOpenURL);
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
@jadidian So, is this the solution for deeplinks and nothing needs to be done in the library?
Also, what about Android? How does this work? Thanks!
@jadidian (or any other)
I am using the following code:
crossroads.addRoute('{kind}/:appId:/:categoryId:/:excursionId:/:screen:', (kind, appId, categoryId, excursionId, screen) => {
Actions.Page1({
deepLinkProps: {
kind,
appId,
categoryId,
excursionId,
screen,
},
});
}
);
However, it appears that the screen is changed more times than once (as it is the main screen) and the "deepLinkProps" are not there on the last render.
Why?
Any ideas, why this cannot work?
@jadidian or anyone else:
What about this on Android?
Activity not started, its current task has been brought to the front
This appears when using the "adb" command:
adb shell am start -W -a android.intent.action.VIEW -d myapp://mobile/app/215/test com.myapp
This means that the listener is not invoked and the deep link is not triggered, because all Android does is bring the app on the front.
Is there any solution to that?
Any news on this?
I've been using the solution posted above without issue. If anyone wanted to turn it into a guide, they could submit a PR to put it into the official docs.
@cridenour Does it work for both iOS and Android?
We don't have an Android version but the underlying Linking library in React Native does have Android support, yes.
using the method described above by @jadidian - this does work on android too.
If i want to be able to deep link to the following url: myappscheme://page-one/some-id
add the following intent-filter to your AndroidManifest.xml file under the .MainActivity:
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="myappscheme"
android:host="page-one"
android:pathPrefix="/" />
</intent-filter>
@aksonov Does V4 address this issue?
It is not difficult to add for v4, but nobody requested. If you need it, create new issue.
Most helpful comment
It turned up to be very easy, I just made a simple project on iOS and it worked... writing the steps here for anyone interested:
1- Open the Xcode project, click on the project root, then "Info", add a URL type at the bottom

2- Follow the instructions on Linking page, you have to add the header's search path in Xcode as described here, then copy paste these two methods in your
AppDelegate.mto enable your JavaScript receive URL events:3-
npm install --save crossroadsCrossroads is a route matching library which does a lot, I guess its too much for simple route matching, but I couldn't find anything simpler... I tried Page first but it didn't work, I guess its intended to work with browser's location only4- My entry point looks like this:
5- My app looks like this... ignore the Redux stuff if you're using something else:
6- Finally, the router:
7- Open Safari, type "test://page-two/123" and you should be taken to
PageTwo