Run react native apps in your browser!
This project uses react-native-web
to create an environment for learning and experimenting with React Native.
The web player is implemented as an iframe
for easy, performant inclusion in any webpage. Transpilation is done in a web worker so the main thread isn't blocked as the page loads.
The web player may be included in your site either as a React component or directly as an iframe
.
If you're using React:
npm install --save react-native-web-player
Then:
import WebPlayer from 'react-native-web-player'
export default () => (
<WebPlayer
style={{width: 800, height: 500}}
/>
)
This component is a simple wrapper around the iframe
that handles encoding parameters for you. While it passes most props along to the iframe
, it has a few extra props:
style
- The style of thediv
which wraps theiframe
(the iframe has100%
width and height).className
- The className of thediv
which wraps theiframe
.baseURL
- Optionally, specify a custom url to load the player from. This url should not include a hash. Defaults to the//cdn.rawgit.com
url as described below.
A umd
build of this React component is available in the dist
directory.
If you're not using React, include the web player in an iframe
.
<iframe width="880" height="425" frameborder="0" src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html"></iframe>
The React component accepts the following props. Props don't need to be URI-encoded or JSON-encoded, as this is handled automatically.
The iframe
accepts the following parameters after the hash in the url. You must URI encode every parameter.
code
- The code to show/run in the player. Defaults to the sample app.title
- An optional title for the player. By default, there is no title.width
- The width of the device. Defaults to210
.scale
- Zoom the device screen. Defaults to1
.platform
- One ofios
orandroid
. Defaults toios
. Currently this changes the phone image, but may also have an effect on how the code is executed in the future.entry
- The filename of the entry file. This is only relevant when showing multiple files with thefiles
parameter. Defaults toindex.js
.initialTab
- The filename of the tab to show by default. This is only relevant when showing multiple files with thefiles
parameter. Defaults toindex.js
.fullscreen
- Show a button to enable fullscreen editing. Defaults tofalse
. Note that the iframe must have theallowfullscreen
attribute for this to work.assetRoot
- Specifies the root url for assetrequire
s. E.g. to requirehttp://localhost:8080/images/hello.png
, you could setassetRoot
to'http://localhost:8080/'
and writerequire('./images/hello.png')
in your code.transpilerTitle
- An optional title for the transpiler output pane. By default, there is no title.playerTitle
- An optional title for the player pane. By default, there is no title.workspaceCSS
- An optional CSS string to apply to the workspaceiframe
.playerCSS
- An optional CSS string to apply to the player'siframe
.playerStyleSheet
- One ofreset
ornone
. Whenreset
, the meyerweb CSS reset is applied to the player'siframe
. Defaults toreset
.
When using the iframe directly, the following parameters must be JSON encoded and then also URI encoded:
-
files
- Array of files to show, one per tab. The format is an array of 2-element arrays, where the first element is the filename (e.g.index.js
) and the second is the code.Example usage:
[['index.js', 'console.log(1)'], ['foo.js', 'console.log(2)']]
Files may be required from one another by name. E.g. if the files are
index.js
andhelpers.js
, in the code ofindex.js
you may writeimport Foo from './helpers'
to use its default export.Use the
entry
andinitialTab
parameters to control which file is executed first and which tab is shown by default. -
panes
- Array of panes to show. Each element is one of:editor
,player
,transpiler
.The default value is:
['editor', 'player']
-
vendorComponents
- Array of 3rd party components to make available to the sandbox. The format is an array of either 2-element or 3-element arrays.-
To use a CommonJS
require
-style loader, pass a 2-element array, where the first element is therequire()
name, and the second is the source url. E.g. to load moment.js: setvendorComponents
to the value[['moment', 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js']]
-
To load a component as a property on
window
, pass a 3-element array, where the first element is therequire()
name, the second element is the window property name (e.g.window.moment
), and the third element is the source url. E.g. to load moment.js: setvendorComponents
to the value[['moment', 'moment', 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js']]
-
-
styles
- An object containing style objects. If you're familiar with React Native, this is thefoo
inStyleSheet.create(foo)
. Styles passed will be vendor-prefixed automatically. The following named styles can be used to override default styling.header
headerText
tab
tabText
tabTextActive
transpilerHeader
transpilerHeaderText
playerPane
playerHeader
playerHeaderText
Example usage:
{header: {backgroundColor: 'red'}}
When used as an iframe
, the easiest way to set the code
parameter is to edit the code in the web player and copy and paste the url when you're done (the url updates automatically as you type).
Alternately, you can manually url-encode the parameters. You can do so programmatically or via the JavaScript console.
encodeURIComponent('Hello World')
# => "Hello%20World"
This project contains static assets that run standalone in the browser. You don't need a server, unless you want to host the assets yourself.
The recommended host is rawgit + MaxCDN. MaxCDN is highly performant and serves over http
and https
. The examples in this readme all point to:
<iframe width="880" height="425" frameborder="0" src="//cdn.rawgit.com/dabbott/react-native-web-player/v2.0.0-alpha.4/index.html"></iframe>
If you prefer, you may access the gh-pages branch directly. This has the advantage of always serving you the latest version, but the drawback of potentially failing on major API changes (along with slower download speeds for the assets).
<iframe width="880" height="425" frameborder="0" src="//dabbott.github.io/react-native-web-player/"></iframe>
- Custom code - https://cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html#platform=ios&code=import%20React%2C%20%7B%20Component%2C%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20Text%2C%20%7D%20from%20'react-native'%3B%0A%0Aconst%20App%20%3D%20()%20%3D%3E%20%3CText%3EHello%20World%3C%2FText%3E%3B%0A%0AAppRegistry.registerComponent('App'%2C%20()%20%3D%3E%20App)%3B
- Android device - https://cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html#platform=android
- Custom title - https://cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html#title=Hello%20Title
- Load moment.js - https://cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html#title=moment.js&vendorComponents=%5B%5B%22moment%22%2C%20%22moment%22%2C%20%22https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fmoment.js%2F2.14.1%2Fmoment.min.js%22%5D%5D&code=import%20React%2C%20%7B%20Component%2C%20%7D%20from%20'react'%3B%0Aimport%20%7B%0A%20%20AppRegistry%2C%0A%20%20StyleSheet%2C%0A%20%20Text%2C%0A%20%20View%2C%0A%7D%20from%20'react-native'%3B%0A%0Aconst%20moment%20%3D%20require('moment')%0A%0Aclass%20App%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.welcome%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%7Bmoment().format('MMMM%20Do%20YYYY%2C%20h%3Amm%3Ass%20a')%7D%0A%20%20%20%20%20%20%20%20%3C%2FText%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20flex%3A%201%2C%0A%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%23F5FCFF'%2C%0A%20%20%7D%2C%0A%20%20welcome%3A%20%7B%0A%20%20%20%20fontSize%3A%2016%2C%0A%20%20%20%20textAlign%3A%20'center'%2C%0A%20%20%20%20margin%3A%2010%2C%0A%20%20%7D%2C%0A%7D)%3B%0A%0AAppRegistry.registerComponent('App'%2C%20()%20%3D%3E%20App)%3B
React/Redux To-do list with persistence
Transpiled output for ES6 const and let
These examples are taken from React Native Express.
Advanced examples tend to have extremely long URLs which load successfully in an iframe
but sometimes fail to load when opened by clicking a link.
npm install
npm run start
=> localhost:8080
npm run build
First publish to npm.
npm version (major|minor|patch)
npm publish
Then publish to gh-pages and make a special tagged release for hosting via CDN.
# Point to the latest release
make TAG=v2.0.0-alpha.4
BSD