|  | @@ -14,7 +14,6 @@ _This guide is currently a work in progress._
 | 
	
		
			
			| 14 | 14 |  - [Add support for File Download](Guide.md#add-support-for-file-download)
 | 
	
		
			
			| 15 | 15 |  - [Communicating between JS and Native](Guide.md#communicating-between-js-and-native)
 | 
	
		
			
			| 16 | 16 |  
 | 
	
		
			
			| 17 |  | -
 | 
	
		
			
			| 18 | 17 |  ### Basic inline HTML
 | 
	
		
			
			| 19 | 18 |  
 | 
	
		
			
			| 20 | 19 |  The simplest way to use the WebView is to simply pipe in the HTML you want to display. Note that setting an `html` source requires the [originWhiteList](Reference.md#originWhiteList) property to be set to `['*']`.
 | 
	
	
		
			
			|  | @@ -48,9 +47,7 @@ import { WebView } from 'react-native-webview';
 | 
	
		
			
			| 48 | 47 |  class MyWeb extends Component {
 | 
	
		
			
			| 49 | 48 |    render() {
 | 
	
		
			
			| 50 | 49 |      return (
 | 
	
		
			
			| 51 |  | -      <WebView
 | 
	
		
			
			| 52 |  | -        source={{uri: 'https://facebook.github.io/react-native/'}}
 | 
	
		
			
			| 53 |  | -      />
 | 
	
		
			
			|  | 50 | +      <WebView source={{ uri: 'https://facebook.github.io/react-native/' }} />
 | 
	
		
			
			| 54 | 51 |      );
 | 
	
		
			
			| 55 | 52 |    }
 | 
	
		
			
			| 56 | 53 |  }
 | 
	
	
		
			
			|  | @@ -71,7 +68,7 @@ class MyWeb extends Component {
 | 
	
		
			
			| 71 | 68 |      return (
 | 
	
		
			
			| 72 | 69 |        <WebView
 | 
	
		
			
			| 73 | 70 |          ref={ref => (this.webview = ref)}
 | 
	
		
			
			| 74 |  | -        source={{uri: 'https://facebook.github.io/react-native/'}}
 | 
	
		
			
			|  | 71 | +        source={{ uri: 'https://facebook.github.io/react-native/' }}
 | 
	
		
			
			| 75 | 72 |          onNavigationStateChange={this.handleWebViewNavigationStateChange}
 | 
	
		
			
			| 76 | 73 |        />
 | 
	
		
			
			| 77 | 74 |      );
 | 
	
	
		
			
			|  | @@ -87,7 +84,7 @@ class MyWeb extends Component {
 | 
	
		
			
			| 87 | 84 |      //   canGoForward?: boolean;
 | 
	
		
			
			| 88 | 85 |      // }
 | 
	
		
			
			| 89 | 86 |      const { url } = newNavState;
 | 
	
		
			
			| 90 |  | -    if (!url) return
 | 
	
		
			
			|  | 87 | +    if (!url) return;
 | 
	
		
			
			| 91 | 88 |  
 | 
	
		
			
			| 92 | 89 |      // handle certain doctypes
 | 
	
		
			
			| 93 | 90 |      if (url.includes('.pdf')) {
 | 
	
	
		
			
			|  | @@ -112,10 +109,48 @@ class MyWeb extends Component {
 | 
	
		
			
			| 112 | 109 |        const redirectTo = 'window.location = "' + newURL + '"';
 | 
	
		
			
			| 113 | 110 |        this.webview.injectJavaScript(redirectTo);
 | 
	
		
			
			| 114 | 111 |      }
 | 
	
		
			
			| 115 |  | -  }
 | 
	
		
			
			|  | 112 | +  };
 | 
	
		
			
			| 116 | 113 |  }
 | 
	
		
			
			| 117 | 114 |  ```
 | 
	
		
			
			| 118 | 115 |  
 | 
	
		
			
			|  | 116 | +#### Intercepting hash URL changes
 | 
	
		
			
			|  | 117 | +
 | 
	
		
			
			|  | 118 | +While `onNavigationStateChange` will trigger on URL changes, it does not trigger when only the hash URL ("anchor") changes, e.g. from `https://example.com/users#list` to `https://example.com/users#help`.
 | 
	
		
			
			|  | 119 | +
 | 
	
		
			
			|  | 120 | +You can inject some JavaScript to wrap the history functions in order to intercept these hash URL changes.
 | 
	
		
			
			|  | 121 | +
 | 
	
		
			
			|  | 122 | +```jsx
 | 
	
		
			
			|  | 123 | +<WebView
 | 
	
		
			
			|  | 124 | +  source={{ uri: someURI }}
 | 
	
		
			
			|  | 125 | +  injectedJavaScript={`
 | 
	
		
			
			|  | 126 | +    (function() {
 | 
	
		
			
			|  | 127 | +      function wrap(fn) {
 | 
	
		
			
			|  | 128 | +        return function wrapper() {
 | 
	
		
			
			|  | 129 | +          var res = fn.apply(this, arguments);
 | 
	
		
			
			|  | 130 | +          window.ReactNativeWebView.postMessage('navigationStateChange');
 | 
	
		
			
			|  | 131 | +          return res;
 | 
	
		
			
			|  | 132 | +        }
 | 
	
		
			
			|  | 133 | +      }
 | 
	
		
			
			|  | 134 | +
 | 
	
		
			
			|  | 135 | +      history.pushState = wrap(history.pushState);
 | 
	
		
			
			|  | 136 | +      history.replaceState = wrap(history.replaceState);
 | 
	
		
			
			|  | 137 | +      window.addEventListener('popstate', function() {
 | 
	
		
			
			|  | 138 | +        window.ReactNativeWebView.postMessage('navigationStateChange');
 | 
	
		
			
			|  | 139 | +      });
 | 
	
		
			
			|  | 140 | +    })();
 | 
	
		
			
			|  | 141 | +
 | 
	
		
			
			|  | 142 | +    true;
 | 
	
		
			
			|  | 143 | +  `}
 | 
	
		
			
			|  | 144 | +  onMessage={({ nativeEvent: state }) => {
 | 
	
		
			
			|  | 145 | +    if (state.data === 'navigationStateChange') {
 | 
	
		
			
			|  | 146 | +      // Navigation state updated, can check state.canGoBack, etc.
 | 
	
		
			
			|  | 147 | +    }
 | 
	
		
			
			|  | 148 | +  }}
 | 
	
		
			
			|  | 149 | +/>
 | 
	
		
			
			|  | 150 | +```
 | 
	
		
			
			|  | 151 | +
 | 
	
		
			
			|  | 152 | +Thanks to [Janic Duplessis](https://github.com/react-native-community/react-native-webview/issues/24#issuecomment-483956651) for this workaround.
 | 
	
		
			
			|  | 153 | +
 | 
	
		
			
			| 119 | 154 |  ### Add support for File Upload
 | 
	
		
			
			| 120 | 155 |  
 | 
	
		
			
			| 121 | 156 |  ##### iOS
 | 
	
	
		
			
			|  | @@ -123,18 +158,21 @@ class MyWeb extends Component {
 | 
	
		
			
			| 123 | 158 |  For iOS, all you need to do is specify the permissions in your `ios/[project]/Info.plist` file:
 | 
	
		
			
			| 124 | 159 |  
 | 
	
		
			
			| 125 | 160 |  Photo capture:
 | 
	
		
			
			|  | 161 | +
 | 
	
		
			
			| 126 | 162 |  ```
 | 
	
		
			
			| 127 | 163 |  <key>NSCameraUsageDescription</key>
 | 
	
		
			
			| 128 | 164 |  <string>Take pictures for certain activities</string>
 | 
	
		
			
			| 129 | 165 |  ```
 | 
	
		
			
			| 130 | 166 |  
 | 
	
		
			
			| 131 | 167 |  Gallery selection:
 | 
	
		
			
			|  | 168 | +
 | 
	
		
			
			| 132 | 169 |  ```
 | 
	
		
			
			| 133 | 170 |  <key>NSPhotoLibraryUsageDescription</key>
 | 
	
		
			
			| 134 | 171 |  <string>Select pictures for certain activities</string>
 | 
	
		
			
			| 135 | 172 |  ```
 | 
	
		
			
			| 136 | 173 |  
 | 
	
		
			
			| 137 | 174 |  Video recording:
 | 
	
		
			
			|  | 175 | +
 | 
	
		
			
			| 138 | 176 |  ```
 | 
	
		
			
			| 139 | 177 |  <key>NSMicrophoneUsageDescription</key>
 | 
	
		
			
			| 140 | 178 |  <string>Need microphone access for recording videos</string>
 | 
	
	
		
			
			|  | @@ -143,6 +181,7 @@ Video recording:
 | 
	
		
			
			| 143 | 181 |  ##### Android
 | 
	
		
			
			| 144 | 182 |  
 | 
	
		
			
			| 145 | 183 |  Add permission in AndroidManifest.xml:
 | 
	
		
			
			|  | 184 | +
 | 
	
		
			
			| 146 | 185 |  ```xml
 | 
	
		
			
			| 147 | 186 |  <manifest ...>
 | 
	
		
			
			| 148 | 187 |    ......
 | 
	
	
		
			
			|  | @@ -173,7 +212,7 @@ WebView.isFileUploadSupported().then(res => {
 | 
	
		
			
			| 173 | 212 |  
 | 
	
		
			
			| 174 | 213 |  ### Multiple Files Upload
 | 
	
		
			
			| 175 | 214 |  
 | 
	
		
			
			| 176 |  | -You can control __single__ or __multiple__ file selection by specifing the [`multiple`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#multiple) attribute on your `input` element:
 | 
	
		
			
			|  | 215 | +You can control **single** or **multiple** file selection by specifing the [`multiple`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#multiple) attribute on your `input` element:
 | 
	
		
			
			| 177 | 216 |  
 | 
	
		
			
			| 178 | 217 |  ```
 | 
	
		
			
			| 179 | 218 |  // multiple file selection
 | 
	
	
		
			
			|  | @@ -190,6 +229,7 @@ You can control __single__ or __multiple__ file selection by specifing the [`mul
 | 
	
		
			
			| 190 | 229 |  For iOS, all you need to do is specify the permissions in your `ios/[project]/Info.plist` file:
 | 
	
		
			
			| 191 | 230 |  
 | 
	
		
			
			| 192 | 231 |  Save to gallery:
 | 
	
		
			
			|  | 232 | +
 | 
	
		
			
			| 193 | 233 |  ```
 | 
	
		
			
			| 194 | 234 |  <key>NSPhotoLibraryAddUsageDescription</key>
 | 
	
		
			
			| 195 | 235 |  <string>Save pictures for certain activities.</string>
 | 
	
	
		
			
			|  | @@ -225,9 +265,9 @@ To accomplish this, React Native WebView exposes three different options:
 | 
	
		
			
			| 225 | 265 |  This is a script that runs immediately after the web page loads for the first time. It only runs once, even if the page is reloaded or navigated away.
 | 
	
		
			
			| 226 | 266 |  
 | 
	
		
			
			| 227 | 267 |  ```jsx
 | 
	
		
			
			| 228 |  | -import React, { Component } from "react";
 | 
	
		
			
			| 229 |  | -import { View } from "react-native";
 | 
	
		
			
			| 230 |  | -import { WebView } from "react-native-webview";
 | 
	
		
			
			|  | 268 | +import React, { Component } from 'react';
 | 
	
		
			
			|  | 269 | +import { View } from 'react-native';
 | 
	
		
			
			|  | 270 | +import { WebView } from 'react-native-webview';
 | 
	
		
			
			| 231 | 271 |  
 | 
	
		
			
			| 232 | 272 |  export default class App extends Component {
 | 
	
		
			
			| 233 | 273 |    render() {
 | 
	
	
		
			
			|  | @@ -241,7 +281,7 @@ export default class App extends Component {
 | 
	
		
			
			| 241 | 281 |          <WebView
 | 
	
		
			
			| 242 | 282 |            source={{
 | 
	
		
			
			| 243 | 283 |              uri:
 | 
	
		
			
			| 244 |  | -              "https://github.com/react-native-community/react-native-webview"
 | 
	
		
			
			|  | 284 | +              'https://github.com/react-native-community/react-native-webview',
 | 
	
		
			
			| 245 | 285 |            }}
 | 
	
		
			
			| 246 | 286 |            injectedJavaScript={runFirst}
 | 
	
		
			
			| 247 | 287 |          />
 | 
	
	
		
			
			|  | @@ -255,7 +295,7 @@ This runs the JavaScript in the `runFirst` string once the page is loaded. In th
 | 
	
		
			
			| 255 | 295 |  
 | 
	
		
			
			| 256 | 296 |  <img alt="screenshot of Github repo" width="200" src="https://user-images.githubusercontent.com/1479215/53609254-e5dc9c00-3b7a-11e9-9118-bc4e520ce6ca.png" />
 | 
	
		
			
			| 257 | 297 |  
 | 
	
		
			
			| 258 |  | -*Under the hood*
 | 
	
		
			
			|  | 298 | +_Under the hood_
 | 
	
		
			
			| 259 | 299 |  
 | 
	
		
			
			| 260 | 300 |  > On iOS, `injectedJavaScript` runs a method on WKWebView called `evaluateJavaScript:completionHandler:`
 | 
	
		
			
			| 261 | 301 |  > On Android, `injectedJavaScript` runs a method on the Android WebView called `evaluateJavascriptWithFallback`
 | 
	
	
		
			
			|  | @@ -265,9 +305,9 @@ This runs the JavaScript in the `runFirst` string once the page is loaded. In th
 | 
	
		
			
			| 265 | 305 |  While convenient, the downside to the previously mentioned `injectedJavaScript` prop is that it only runs once. That's why we also expose a method on the webview ref called `injectJavaScript` (note the slightly different name!).
 | 
	
		
			
			| 266 | 306 |  
 | 
	
		
			
			| 267 | 307 |  ```jsx
 | 
	
		
			
			| 268 |  | -import React, { Component } from "react";
 | 
	
		
			
			| 269 |  | -import { View } from "react-native";
 | 
	
		
			
			| 270 |  | -import { WebView } from "react-native-webview";
 | 
	
		
			
			|  | 308 | +import React, { Component } from 'react';
 | 
	
		
			
			|  | 309 | +import { View } from 'react-native';
 | 
	
		
			
			|  | 310 | +import { WebView } from 'react-native-webview';
 | 
	
		
			
			| 271 | 311 |  
 | 
	
		
			
			| 272 | 312 |  export default class App extends Component {
 | 
	
		
			
			| 273 | 313 |    render() {
 | 
	
	
		
			
			|  | @@ -286,7 +326,7 @@ export default class App extends Component {
 | 
	
		
			
			| 286 | 326 |            ref={r => (this.webref = r)}
 | 
	
		
			
			| 287 | 327 |            source={{
 | 
	
		
			
			| 288 | 328 |              uri:
 | 
	
		
			
			| 289 |  | -              "https://github.com/react-native-community/react-native-webview"
 | 
	
		
			
			|  | 329 | +              'https://github.com/react-native-community/react-native-webview',
 | 
	
		
			
			| 290 | 330 |            }}
 | 
	
		
			
			| 291 | 331 |          />
 | 
	
		
			
			| 292 | 332 |        </View>
 | 
	
	
		
			
			|  | @@ -299,7 +339,7 @@ After 3 seconds, this code turns the background blue:
 | 
	
		
			
			| 299 | 339 |  
 | 
	
		
			
			| 300 | 340 |  <img alt="Screenshot of app showing injected javascript" width="200" src="https://user-images.githubusercontent.com/1479215/53670433-93a98280-3c2f-11e9-85a5-0e4650993817.png" />
 | 
	
		
			
			| 301 | 341 |  
 | 
	
		
			
			| 302 |  | -*Under the hood*
 | 
	
		
			
			|  | 342 | +_Under the hood_
 | 
	
		
			
			| 303 | 343 |  
 | 
	
		
			
			| 304 | 344 |  > On iOS, `injectJavaScript` calls WKWebView's `evaluateJS:andThen:`
 | 
	
		
			
			| 305 | 345 |  > On Android, `injectJavaScript` calls Android WebView's `evaluateJavascriptWithFallback` method
 | 
	
	
		
			
			|  | @@ -313,9 +353,9 @@ You _must_ set `onMessage` or the `window.ReactNativeWebView.postMessage` method
 | 
	
		
			
			| 313 | 353 |  `window.ReactNativeWebView.postMessage` only accepts one argument which must be a string.
 | 
	
		
			
			| 314 | 354 |  
 | 
	
		
			
			| 315 | 355 |  ```jsx
 | 
	
		
			
			| 316 |  | -import React, { Component } from "react";
 | 
	
		
			
			| 317 |  | -import { View } from "react-native";
 | 
	
		
			
			| 318 |  | -import { WebView } from "react-native-webview";
 | 
	
		
			
			|  | 356 | +import React, { Component } from 'react';
 | 
	
		
			
			|  | 357 | +import { View } from 'react-native';
 | 
	
		
			
			|  | 358 | +import { WebView } from 'react-native-webview';
 | 
	
		
			
			| 319 | 359 |  
 | 
	
		
			
			| 320 | 360 |  export default class App extends Component {
 | 
	
		
			
			| 321 | 361 |    render() {
 | 
	
	
		
			
			|  | @@ -349,4 +389,3 @@ export default class App extends Component {
 | 
	
		
			
			| 349 | 389 |  This code will result in this alert:
 | 
	
		
			
			| 350 | 390 |  
 | 
	
		
			
			| 351 | 391 |  <img alt="Alert showing communication from web page to React Native" width="200" src="https://user-images.githubusercontent.com/1479215/53671269-7e822300-3c32-11e9-9937-7ddc34ba8af3.png" />
 | 
	
		
			
			| 352 |  | -
 |