- Sotiris Karapostolou
Embedding youtube videos in a react native app with WebView, Modal && react-navigation
Recently I had to embed a youtube video in a react native app for the project I am working on. Ideally you would use this package react-native-youtube but unfortunately it doesn't support Expo workflow, so at that moment I realized I had to improvise (my favorite moment as a web-developer).

Setting up the Webview
Add this package -- react-native-webview to your project
Now let's create the VideoModal component.
#VideoModal.js
import { Modal } from 'react-native';
import WebView from 'react-native-webview';
const _VALIDURL = /^(https?\:\/\/)?((www\.)?youtube\.com|youtu\.?be)\/.+$/;
const _FINDID = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/;
const { width } = Dimensions.get('window');
const VideoModal = ({ handleClose, open, urlSource }) => {
const videoRef = useRef();
const videoId = useRef();
const [canGoBack, setCanGoBack] = useState(false);
const isYoutubeVideo = _VALIDURL.test(urlSource);
if (isYoutubeVideo) {
videoId.current = urlSource.match(_FINDID)[1];
}
const handleBackButton = () => {
videoRef.current.goBack();
};
return (
<Modal
animationType="fade"
transparent={true}
onRequestClose={canGoBack ? handleBackButton : handleClose}
visible={open}
>
<View style={{ flex: 1 }}>
<WebView
style={{ width: width }}
javaScriptEnabled={true}
ref={videoRef}
startInLoadingState={true}
renderLoading={() => (
<View style={{ flex: 1}}>
<ActivityIndicator />
</View>
)}
onNavigationStateChange={({ canGoBack }) => {
setCanGoBack(canGoBack);
}}
source={{
uri: isYoutubeVideo
?`https://www.youtube.com/embed/${videoId.current}/?rel=0&showinfo=0&controls=1`
: urlSource,
}}
/>
{Platform.OS === 'ios' && (
<TouchableHighlight onPress={handleClose}>
<Text style={styles.textStyle}>Close Video</Text>
</TouchableHighlight>
)}
</View>
</Modal>
);
};
The VideoModal component in not responsible for opening and closing the modal but showing the video to the user so it receives these 3 props. The handleClose to be able to close the modal, the open state of the modal and the urlSource.
I ll walk you though the code, we’ve done a few things here:
Wrapped the WebView with the Modal component, for more info about the Modal you can go here here
Define the _VALIDURL && _FINDID helpers to validate the video url and extract the video ID
Set the source property so that the webview will load
`https://www.youtube.com/embed/${videoId.current}/?rel=0&showinfo=0&controls=1`
#For more info about the url parameters see YouTube Player Parameters
Added a ref property so we can easily get a hold of the WebView later on
Added a loading indicator by tweaking thrse two props startInLoadingState && renderLoading
Wiring Up the back button to navigate back
We've done this by:
Adding the onRequestClose prop to the Modal component.
The reason we use this prop is because if your app shows an opened Modal, BackHandler will not publish any events for more info see this
Keeping track of the navigation state thought the onNavigationStateChange prop.
We pull out the canGoBack prop and set it to our component state.This property tells us if the user has navigated past the original page we loaded and so can go back towards the original page.
Binding the handleBackButton function on the onRequestClose prop
Thanks to our callback, we now are able to navigate back or exit the modal depending on the canGoBack state.
Now Let's Bring in the VideoModal component into the CourseDetail
#CourseDetail.js
import VideoModal from 'components/VideoModal';
const CourseDetail = ({ navigation }) => {
const [modalVisible, setModalVisible] = useState(false);
const [urlSource, setUrlSource] = useState(null);
const handleOpenModal = (url) => {
setUrlSource(url);
setModalVisible(true);
};
return (
<View style={styles.container}>
{modalVisible && (
<VideoModal
open={modalVisible}
urlSource={urlSource}
handleClose={() => setModalVisible(false)}
/>
)}
<CourseItem
lesson={lesson}
handleOpenVideo={handleOpenModal}
/>
. . . .
</View>
};
Well, I hope that helped! Right to the point! If you like this and want to support me on making more stories you can contact me on Linkedin
#reactNative #javascript #WebView #YoutubeIframe #Modals #reactNavigation #hooks #javascript #youtubePlayer