How to make Puppeteer work with a reactJS app2019 Community Moderator ElectionPuppeteer - How to connect WSEndpoint using local IP address?Running puppeteer with containerized chrome binary from another containerHow to run Puppeteer code in any web browser?How do JavaScript closures work?How do I check if an element is hidden in jQuery?How do I remove a property from a JavaScript object?How do I redirect to another webpage?How does JavaScript .prototype work?How do I include a JavaScript file in another JavaScript file?How do I make the first letter of a string uppercase in JavaScript?How to check whether a string contains a substring in JavaScript?How do I remove a particular element from an array in JavaScript?How do I return the response from an asynchronous call?

Why do tuner card drivers fail to build after kernel update to 4.4.0-143-generic?

Is there a symmetric-key algorithm which we can use for creating a signature?

How are passwords stolen from companies if they only store hashes?

I got the following comment from a reputed math journal. What does it mean?

How could a scammer know the apps on my phone / iTunes account?

What is the purpose or proof behind chain rule?

Have the tides ever turned twice on any open problem?

Examples of transfinite towers

Is it ever recommended to use mean/multiple imputation when using tree-based predictive models?

How could an airship be repaired midflight?

PTIJ: Who should I vote for? (21st Knesset Edition)

Why is a white electrical wire connected to 2 black wires?

Is it insecure to send a password in a `curl` command?

Four married couples attend a party. Each person shakes hands with every other person, except their own spouse, exactly once. How many handshakes?

A diagram about partial derivatives of f(x,y)

A single argument pattern definition applies to multiple-argument patterns?

Employee lack of ownership

Is Manda another name for Saturn (Shani)?

Are ETF trackers fundamentally better than individual stocks?

Should Stotras and Mantras be recited aloud?

Do I need life insurance if I can cover my own funeral costs?

Is it normal that my co-workers at a fitness company criticize my food choices?

How difficult is it to simply disable/disengage the MCAS on Boeing 737 Max 8 & 9 Aircraft?

This word with a lot of past tenses



How to make Puppeteer work with a reactJS app



2019 Community Moderator ElectionPuppeteer - How to connect WSEndpoint using local IP address?Running puppeteer with containerized chrome binary from another containerHow to run Puppeteer code in any web browser?How do JavaScript closures work?How do I check if an element is hidden in jQuery?How do I remove a property from a JavaScript object?How do I redirect to another webpage?How does JavaScript .prototype work?How do I include a JavaScript file in another JavaScript file?How do I make the first letter of a string uppercase in JavaScript?How to check whether a string contains a substring in JavaScript?How do I remove a particular element from an array in JavaScript?How do I return the response from an asynchronous call?










3















I am fairly new to React and I am developing an app which will take actual screenshots of a web page and the app can draw and add doodles on top of the screenshot taken. I initially used html2canvas and domToImage to take client-side screenshots but it doesn't render the image exactly as it is shown in the web page.



Reddit user /pamblam0 suggested I look into Google's Puppeteer. How it works is that it launches a headless chromium browser which goes to my react app on localhost then gets a screenshot of that whole page easily. My problem however, is that puppeteer doesn't play nice inside a react app. It gives me a ws error which, as explained on a google search can be fixed by simply installing ws (which doesn't work by the way).



What happens now my puppeteer script works out my react app. From what I understand it doesn't work with client side app (I might be wrong). What I want to happen is that whenever I click the button from my react app, puppeteer should execute and return a base64 string which will then be passed to a component in my react app.



Here is what I've done so far.



puppeteerApp.js



const puppeteer = require('puppeteer');

const takeScreenshot = async () =>
puppeteer.launch().then(async browser =>
const page = await browser.newPage();
const options =
path: 'saved_images/webshot.png',
encoding: 'base64'

await page.goto('http://localhost:3000/', waitUntil: 'networkidle2' );
const elem = await page.$('iframe').then(async (iframe) =>
return await iframe.screenshot(options)
);

await browser.close()
);


takeScreenshot();


Code from react app.
App.js



import React, Component from 'react';
import ScreenshotsContainer from './containers/ScreenshotsContainer/ScreenshotsContainer'
import ImageContainer from './containers/ImageContainer/ImageContainer';
import html2canvas from 'html2canvas';
import domtoimage from 'dom-to-image';
import Button from './components/UI/Button/Button'
import classes from './App.module.css';
import CSSTransition from 'react-transition-group'
import ToastContainer, toast from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';


class App extends Component

constructor(props)
super(props);
this.state =
imgURIArray: [],
img: null,
showImageContainer: false,
showScreenshotContainer: false,
selectedImageURI: null,
showSaveAnimation: false,
showNotify: false




storeImageToArrayHandler = (imgURI) =>
if (imgURI !== "")
this.setState( imgURIArray: [...this.state.imgURIArray, imgURI] , () =>
this.setState( showImageContainer: !this.state.showImageContainer )
)



getScreenshotHandler = () =>
//use puppeteer here!!!




getSelectedImageFromContainerHandler(selectedImageURI)
this.setState(
selectedImageURI: selectedImageURI,
showImageContainer: !this.state.showImageContainer
)



showImageContainerHandler(showImageContainer)
this.setState( showImageContainer: showImageContainer )


showScreenshotContainerHandler = () =>
this.setState( showScreenshotContainer: !this.state.showScreenshotContainer )

notify = (submitSuccessful, msg) =>
let message = msg ? msg : ""
submitSuccessful ?
toast.success(message,
autoClose: 3000,
position: toast.POSITION.TOP_CENTER
)
:
toast.error(message,
position: toast.POSITION.TOP_CENTER
);


render()
let buttonOps = (
<CSSTransition
in=!this.state.showScreenshotContainer
appear=true
timeout=300
classNames="fade"
>
<div className=classes.optionButtons>
<Button icon="fas fa-camera" type="button-success" gridClass="" buttonName="" style= width: "100%", height: "70px" onClick=() => this.getScreenshotHandler />
<Button icon="fas fa-images" type="button-primary " gridClass="" buttonName="" style= width: "100%", height: "70px" onClick=() => this.showScreenshotContainerHandler />
</div>
</CSSTransition>
)

return (
<div>

this.state.showImageContainer ?
<div>
<ImageContainer
img=this.state.img
showImageContainer=showImageContainer => this.showImageContainerHandler(showImageContainer)
storeImageToArrayHandler=imgURI => this.storeImageToArrayHandler(imgURI)
notify=(submitSuccessful, msg) => this.notify(submitSuccessful, msg)
/>
</div>
: null

<CSSTransition
in=this.state.showScreenshotContainer
appear=true
timeout=300
classNames="slide"
unmountOnExit
onExited=() =>
this.setState( showScreenshotContainer: false )

>
<ScreenshotsContainer
imgURIArray=this.state.imgURIArray
getSelectedImageFromContainerHandler=imgURI => this.getSelectedImageFromContainerHandler(imgURI)
showScreenshotContainerHandler=() => this.showScreenshotContainerHandler
notify=(submitSuccessful, msg) => this.notify(submitSuccessful, msg)
/>

</CSSTransition>
this.state.showImageContainer ? null : buttonOps
/* <button onClick=this.notify>Notify !</button> */
<ToastContainer />

</div >
);



export default App;


Any help would be appreciated. Thanks!










share|improve this question



















  • 1





    You will need a server. Please refer to stackoverflow.com/a/51750943/6161265, stackoverflow.com/a/51732895/6161265 stackoverflow.com/a/54654516/6161265

    – Md. Abu Taher
    Mar 7 at 3:17












  • Possible duplicate of How to run Puppeteer code in any web browser?

    – Md. Abu Taher
    Mar 7 at 3:19















3















I am fairly new to React and I am developing an app which will take actual screenshots of a web page and the app can draw and add doodles on top of the screenshot taken. I initially used html2canvas and domToImage to take client-side screenshots but it doesn't render the image exactly as it is shown in the web page.



Reddit user /pamblam0 suggested I look into Google's Puppeteer. How it works is that it launches a headless chromium browser which goes to my react app on localhost then gets a screenshot of that whole page easily. My problem however, is that puppeteer doesn't play nice inside a react app. It gives me a ws error which, as explained on a google search can be fixed by simply installing ws (which doesn't work by the way).



What happens now my puppeteer script works out my react app. From what I understand it doesn't work with client side app (I might be wrong). What I want to happen is that whenever I click the button from my react app, puppeteer should execute and return a base64 string which will then be passed to a component in my react app.



Here is what I've done so far.



puppeteerApp.js



const puppeteer = require('puppeteer');

const takeScreenshot = async () =>
puppeteer.launch().then(async browser =>
const page = await browser.newPage();
const options =
path: 'saved_images/webshot.png',
encoding: 'base64'

await page.goto('http://localhost:3000/', waitUntil: 'networkidle2' );
const elem = await page.$('iframe').then(async (iframe) =>
return await iframe.screenshot(options)
);

await browser.close()
);


takeScreenshot();


Code from react app.
App.js



import React, Component from 'react';
import ScreenshotsContainer from './containers/ScreenshotsContainer/ScreenshotsContainer'
import ImageContainer from './containers/ImageContainer/ImageContainer';
import html2canvas from 'html2canvas';
import domtoimage from 'dom-to-image';
import Button from './components/UI/Button/Button'
import classes from './App.module.css';
import CSSTransition from 'react-transition-group'
import ToastContainer, toast from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';


class App extends Component

constructor(props)
super(props);
this.state =
imgURIArray: [],
img: null,
showImageContainer: false,
showScreenshotContainer: false,
selectedImageURI: null,
showSaveAnimation: false,
showNotify: false




storeImageToArrayHandler = (imgURI) =>
if (imgURI !== "")
this.setState( imgURIArray: [...this.state.imgURIArray, imgURI] , () =>
this.setState( showImageContainer: !this.state.showImageContainer )
)



getScreenshotHandler = () =>
//use puppeteer here!!!




getSelectedImageFromContainerHandler(selectedImageURI)
this.setState(
selectedImageURI: selectedImageURI,
showImageContainer: !this.state.showImageContainer
)



showImageContainerHandler(showImageContainer)
this.setState( showImageContainer: showImageContainer )


showScreenshotContainerHandler = () =>
this.setState( showScreenshotContainer: !this.state.showScreenshotContainer )

notify = (submitSuccessful, msg) =>
let message = msg ? msg : ""
submitSuccessful ?
toast.success(message,
autoClose: 3000,
position: toast.POSITION.TOP_CENTER
)
:
toast.error(message,
position: toast.POSITION.TOP_CENTER
);


render()
let buttonOps = (
<CSSTransition
in=!this.state.showScreenshotContainer
appear=true
timeout=300
classNames="fade"
>
<div className=classes.optionButtons>
<Button icon="fas fa-camera" type="button-success" gridClass="" buttonName="" style= width: "100%", height: "70px" onClick=() => this.getScreenshotHandler />
<Button icon="fas fa-images" type="button-primary " gridClass="" buttonName="" style= width: "100%", height: "70px" onClick=() => this.showScreenshotContainerHandler />
</div>
</CSSTransition>
)

return (
<div>

this.state.showImageContainer ?
<div>
<ImageContainer
img=this.state.img
showImageContainer=showImageContainer => this.showImageContainerHandler(showImageContainer)
storeImageToArrayHandler=imgURI => this.storeImageToArrayHandler(imgURI)
notify=(submitSuccessful, msg) => this.notify(submitSuccessful, msg)
/>
</div>
: null

<CSSTransition
in=this.state.showScreenshotContainer
appear=true
timeout=300
classNames="slide"
unmountOnExit
onExited=() =>
this.setState( showScreenshotContainer: false )

>
<ScreenshotsContainer
imgURIArray=this.state.imgURIArray
getSelectedImageFromContainerHandler=imgURI => this.getSelectedImageFromContainerHandler(imgURI)
showScreenshotContainerHandler=() => this.showScreenshotContainerHandler
notify=(submitSuccessful, msg) => this.notify(submitSuccessful, msg)
/>

</CSSTransition>
this.state.showImageContainer ? null : buttonOps
/* <button onClick=this.notify>Notify !</button> */
<ToastContainer />

</div >
);



export default App;


Any help would be appreciated. Thanks!










share|improve this question



















  • 1





    You will need a server. Please refer to stackoverflow.com/a/51750943/6161265, stackoverflow.com/a/51732895/6161265 stackoverflow.com/a/54654516/6161265

    – Md. Abu Taher
    Mar 7 at 3:17












  • Possible duplicate of How to run Puppeteer code in any web browser?

    – Md. Abu Taher
    Mar 7 at 3:19













3












3








3








I am fairly new to React and I am developing an app which will take actual screenshots of a web page and the app can draw and add doodles on top of the screenshot taken. I initially used html2canvas and domToImage to take client-side screenshots but it doesn't render the image exactly as it is shown in the web page.



Reddit user /pamblam0 suggested I look into Google's Puppeteer. How it works is that it launches a headless chromium browser which goes to my react app on localhost then gets a screenshot of that whole page easily. My problem however, is that puppeteer doesn't play nice inside a react app. It gives me a ws error which, as explained on a google search can be fixed by simply installing ws (which doesn't work by the way).



What happens now my puppeteer script works out my react app. From what I understand it doesn't work with client side app (I might be wrong). What I want to happen is that whenever I click the button from my react app, puppeteer should execute and return a base64 string which will then be passed to a component in my react app.



Here is what I've done so far.



puppeteerApp.js



const puppeteer = require('puppeteer');

const takeScreenshot = async () =>
puppeteer.launch().then(async browser =>
const page = await browser.newPage();
const options =
path: 'saved_images/webshot.png',
encoding: 'base64'

await page.goto('http://localhost:3000/', waitUntil: 'networkidle2' );
const elem = await page.$('iframe').then(async (iframe) =>
return await iframe.screenshot(options)
);

await browser.close()
);


takeScreenshot();


Code from react app.
App.js



import React, Component from 'react';
import ScreenshotsContainer from './containers/ScreenshotsContainer/ScreenshotsContainer'
import ImageContainer from './containers/ImageContainer/ImageContainer';
import html2canvas from 'html2canvas';
import domtoimage from 'dom-to-image';
import Button from './components/UI/Button/Button'
import classes from './App.module.css';
import CSSTransition from 'react-transition-group'
import ToastContainer, toast from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';


class App extends Component

constructor(props)
super(props);
this.state =
imgURIArray: [],
img: null,
showImageContainer: false,
showScreenshotContainer: false,
selectedImageURI: null,
showSaveAnimation: false,
showNotify: false




storeImageToArrayHandler = (imgURI) =>
if (imgURI !== "")
this.setState( imgURIArray: [...this.state.imgURIArray, imgURI] , () =>
this.setState( showImageContainer: !this.state.showImageContainer )
)



getScreenshotHandler = () =>
//use puppeteer here!!!




getSelectedImageFromContainerHandler(selectedImageURI)
this.setState(
selectedImageURI: selectedImageURI,
showImageContainer: !this.state.showImageContainer
)



showImageContainerHandler(showImageContainer)
this.setState( showImageContainer: showImageContainer )


showScreenshotContainerHandler = () =>
this.setState( showScreenshotContainer: !this.state.showScreenshotContainer )

notify = (submitSuccessful, msg) =>
let message = msg ? msg : ""
submitSuccessful ?
toast.success(message,
autoClose: 3000,
position: toast.POSITION.TOP_CENTER
)
:
toast.error(message,
position: toast.POSITION.TOP_CENTER
);


render()
let buttonOps = (
<CSSTransition
in=!this.state.showScreenshotContainer
appear=true
timeout=300
classNames="fade"
>
<div className=classes.optionButtons>
<Button icon="fas fa-camera" type="button-success" gridClass="" buttonName="" style= width: "100%", height: "70px" onClick=() => this.getScreenshotHandler />
<Button icon="fas fa-images" type="button-primary " gridClass="" buttonName="" style= width: "100%", height: "70px" onClick=() => this.showScreenshotContainerHandler />
</div>
</CSSTransition>
)

return (
<div>

this.state.showImageContainer ?
<div>
<ImageContainer
img=this.state.img
showImageContainer=showImageContainer => this.showImageContainerHandler(showImageContainer)
storeImageToArrayHandler=imgURI => this.storeImageToArrayHandler(imgURI)
notify=(submitSuccessful, msg) => this.notify(submitSuccessful, msg)
/>
</div>
: null

<CSSTransition
in=this.state.showScreenshotContainer
appear=true
timeout=300
classNames="slide"
unmountOnExit
onExited=() =>
this.setState( showScreenshotContainer: false )

>
<ScreenshotsContainer
imgURIArray=this.state.imgURIArray
getSelectedImageFromContainerHandler=imgURI => this.getSelectedImageFromContainerHandler(imgURI)
showScreenshotContainerHandler=() => this.showScreenshotContainerHandler
notify=(submitSuccessful, msg) => this.notify(submitSuccessful, msg)
/>

</CSSTransition>
this.state.showImageContainer ? null : buttonOps
/* <button onClick=this.notify>Notify !</button> */
<ToastContainer />

</div >
);



export default App;


Any help would be appreciated. Thanks!










share|improve this question
















I am fairly new to React and I am developing an app which will take actual screenshots of a web page and the app can draw and add doodles on top of the screenshot taken. I initially used html2canvas and domToImage to take client-side screenshots but it doesn't render the image exactly as it is shown in the web page.



Reddit user /pamblam0 suggested I look into Google's Puppeteer. How it works is that it launches a headless chromium browser which goes to my react app on localhost then gets a screenshot of that whole page easily. My problem however, is that puppeteer doesn't play nice inside a react app. It gives me a ws error which, as explained on a google search can be fixed by simply installing ws (which doesn't work by the way).



What happens now my puppeteer script works out my react app. From what I understand it doesn't work with client side app (I might be wrong). What I want to happen is that whenever I click the button from my react app, puppeteer should execute and return a base64 string which will then be passed to a component in my react app.



Here is what I've done so far.



puppeteerApp.js



const puppeteer = require('puppeteer');

const takeScreenshot = async () =>
puppeteer.launch().then(async browser =>
const page = await browser.newPage();
const options =
path: 'saved_images/webshot.png',
encoding: 'base64'

await page.goto('http://localhost:3000/', waitUntil: 'networkidle2' );
const elem = await page.$('iframe').then(async (iframe) =>
return await iframe.screenshot(options)
);

await browser.close()
);


takeScreenshot();


Code from react app.
App.js



import React, Component from 'react';
import ScreenshotsContainer from './containers/ScreenshotsContainer/ScreenshotsContainer'
import ImageContainer from './containers/ImageContainer/ImageContainer';
import html2canvas from 'html2canvas';
import domtoimage from 'dom-to-image';
import Button from './components/UI/Button/Button'
import classes from './App.module.css';
import CSSTransition from 'react-transition-group'
import ToastContainer, toast from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';


class App extends Component

constructor(props)
super(props);
this.state =
imgURIArray: [],
img: null,
showImageContainer: false,
showScreenshotContainer: false,
selectedImageURI: null,
showSaveAnimation: false,
showNotify: false




storeImageToArrayHandler = (imgURI) =>
if (imgURI !== "")
this.setState( imgURIArray: [...this.state.imgURIArray, imgURI] , () =>
this.setState( showImageContainer: !this.state.showImageContainer )
)



getScreenshotHandler = () =>
//use puppeteer here!!!




getSelectedImageFromContainerHandler(selectedImageURI)
this.setState(
selectedImageURI: selectedImageURI,
showImageContainer: !this.state.showImageContainer
)



showImageContainerHandler(showImageContainer)
this.setState( showImageContainer: showImageContainer )


showScreenshotContainerHandler = () =>
this.setState( showScreenshotContainer: !this.state.showScreenshotContainer )

notify = (submitSuccessful, msg) =>
let message = msg ? msg : ""
submitSuccessful ?
toast.success(message,
autoClose: 3000,
position: toast.POSITION.TOP_CENTER
)
:
toast.error(message,
position: toast.POSITION.TOP_CENTER
);


render()
let buttonOps = (
<CSSTransition
in=!this.state.showScreenshotContainer
appear=true
timeout=300
classNames="fade"
>
<div className=classes.optionButtons>
<Button icon="fas fa-camera" type="button-success" gridClass="" buttonName="" style= width: "100%", height: "70px" onClick=() => this.getScreenshotHandler />
<Button icon="fas fa-images" type="button-primary " gridClass="" buttonName="" style= width: "100%", height: "70px" onClick=() => this.showScreenshotContainerHandler />
</div>
</CSSTransition>
)

return (
<div>

this.state.showImageContainer ?
<div>
<ImageContainer
img=this.state.img
showImageContainer=showImageContainer => this.showImageContainerHandler(showImageContainer)
storeImageToArrayHandler=imgURI => this.storeImageToArrayHandler(imgURI)
notify=(submitSuccessful, msg) => this.notify(submitSuccessful, msg)
/>
</div>
: null

<CSSTransition
in=this.state.showScreenshotContainer
appear=true
timeout=300
classNames="slide"
unmountOnExit
onExited=() =>
this.setState( showScreenshotContainer: false )

>
<ScreenshotsContainer
imgURIArray=this.state.imgURIArray
getSelectedImageFromContainerHandler=imgURI => this.getSelectedImageFromContainerHandler(imgURI)
showScreenshotContainerHandler=() => this.showScreenshotContainerHandler
notify=(submitSuccessful, msg) => this.notify(submitSuccessful, msg)
/>

</CSSTransition>
this.state.showImageContainer ? null : buttonOps
/* <button onClick=this.notify>Notify !</button> */
<ToastContainer />

</div >
);



export default App;


Any help would be appreciated. Thanks!







javascript reactjs puppeteer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 6 at 20:48







NoobNewb

















asked Mar 6 at 20:41









NoobNewbNoobNewb

6317




6317







  • 1





    You will need a server. Please refer to stackoverflow.com/a/51750943/6161265, stackoverflow.com/a/51732895/6161265 stackoverflow.com/a/54654516/6161265

    – Md. Abu Taher
    Mar 7 at 3:17












  • Possible duplicate of How to run Puppeteer code in any web browser?

    – Md. Abu Taher
    Mar 7 at 3:19












  • 1





    You will need a server. Please refer to stackoverflow.com/a/51750943/6161265, stackoverflow.com/a/51732895/6161265 stackoverflow.com/a/54654516/6161265

    – Md. Abu Taher
    Mar 7 at 3:17












  • Possible duplicate of How to run Puppeteer code in any web browser?

    – Md. Abu Taher
    Mar 7 at 3:19







1




1





You will need a server. Please refer to stackoverflow.com/a/51750943/6161265, stackoverflow.com/a/51732895/6161265 stackoverflow.com/a/54654516/6161265

– Md. Abu Taher
Mar 7 at 3:17






You will need a server. Please refer to stackoverflow.com/a/51750943/6161265, stackoverflow.com/a/51732895/6161265 stackoverflow.com/a/54654516/6161265

– Md. Abu Taher
Mar 7 at 3:17














Possible duplicate of How to run Puppeteer code in any web browser?

– Md. Abu Taher
Mar 7 at 3:19





Possible duplicate of How to run Puppeteer code in any web browser?

– Md. Abu Taher
Mar 7 at 3:19












1 Answer
1






active

oldest

votes


















1














Your React.js application runs on the client-side (in the browser). Puppeteer cannot run inside that environment as you cannot start a full browser inside the browser.



What you need is a server which does that for you. You could ether offer a HTTP endpoint (option 1) or expose your puppeteer Websocket (option 2):



Option 1: Provide a HTTP endpoint



For this option, you setup a server which handles the incoming request and runs the task (making a screenshot) for you:



server.js



const puppeteer = require('puppeteer');
const express = require('express');

const app = express();

app.get('/screenshot', async (req, res) =>
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(req.query.url); // URL is given by the "user" (your client-side application)
const screenshotBuffer = await page.screenshot(path: 'example.png');

// Respond with the image
res.writeHead(200,
'Content-Type': 'image/png',
'Content-Length': screenshotBuffer.length
);
res.end(screenshotBuffer);

await browser.close();
)

app.listen(4000);


Start the application with node server.js and you can now pass the URL to your server and get a screenshot back from your server: http://localhost:4000/screenshot?url=https://example.com/



The response from the server could then be used as as the source of an image element in your application.



Option 2: Exposing the puppeteer Websocket to the client



You could also control the browser (which runs on the server) from the client-side by by exposing the Websocket.



For that you need to expose the Websocket of your server like this:



server.js



const puppeteer = require('puppeteer');

(async () =>
const browser = await puppeteer.launch();
const browserWSEndpoint = browser.wsEndpoint();
browser.disconnect(); // Disconnect from the browser, but don't close it
console.log(browserWSEndpoint); // Communicate the Websocket URL to the client-side
// example output: ws://127.0.0.1:55620/devtools/browser/e62ec4c8-1f05-42a1-86ce-7b8dd3403f91
)();


Now you can control the browser (running on the server) form the client-side with a puppeteer bundle for the client. In this scenario you could now connect to the browser via puppeteer.connect and make a screenshot that way.



I would strongly recommend using option 1, as in option 2 you are fully exposing your running browser to the client. Even with option 1, you still need to handle user input validation, timeouts, navigation errors, etc.






share|improve this answer

























  • I went ahead and followed option 1. I got it working! Thank you! I didn't think something as easy as taking a screenshot of your browser requires a lot of steps. I also installed the cors library just to get past the cors error I was having.

    – NoobNewb
    Mar 7 at 18:11










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55031823%2fhow-to-make-puppeteer-work-with-a-reactjs-app%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Your React.js application runs on the client-side (in the browser). Puppeteer cannot run inside that environment as you cannot start a full browser inside the browser.



What you need is a server which does that for you. You could ether offer a HTTP endpoint (option 1) or expose your puppeteer Websocket (option 2):



Option 1: Provide a HTTP endpoint



For this option, you setup a server which handles the incoming request and runs the task (making a screenshot) for you:



server.js



const puppeteer = require('puppeteer');
const express = require('express');

const app = express();

app.get('/screenshot', async (req, res) =>
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(req.query.url); // URL is given by the "user" (your client-side application)
const screenshotBuffer = await page.screenshot(path: 'example.png');

// Respond with the image
res.writeHead(200,
'Content-Type': 'image/png',
'Content-Length': screenshotBuffer.length
);
res.end(screenshotBuffer);

await browser.close();
)

app.listen(4000);


Start the application with node server.js and you can now pass the URL to your server and get a screenshot back from your server: http://localhost:4000/screenshot?url=https://example.com/



The response from the server could then be used as as the source of an image element in your application.



Option 2: Exposing the puppeteer Websocket to the client



You could also control the browser (which runs on the server) from the client-side by by exposing the Websocket.



For that you need to expose the Websocket of your server like this:



server.js



const puppeteer = require('puppeteer');

(async () =>
const browser = await puppeteer.launch();
const browserWSEndpoint = browser.wsEndpoint();
browser.disconnect(); // Disconnect from the browser, but don't close it
console.log(browserWSEndpoint); // Communicate the Websocket URL to the client-side
// example output: ws://127.0.0.1:55620/devtools/browser/e62ec4c8-1f05-42a1-86ce-7b8dd3403f91
)();


Now you can control the browser (running on the server) form the client-side with a puppeteer bundle for the client. In this scenario you could now connect to the browser via puppeteer.connect and make a screenshot that way.



I would strongly recommend using option 1, as in option 2 you are fully exposing your running browser to the client. Even with option 1, you still need to handle user input validation, timeouts, navigation errors, etc.






share|improve this answer

























  • I went ahead and followed option 1. I got it working! Thank you! I didn't think something as easy as taking a screenshot of your browser requires a lot of steps. I also installed the cors library just to get past the cors error I was having.

    – NoobNewb
    Mar 7 at 18:11















1














Your React.js application runs on the client-side (in the browser). Puppeteer cannot run inside that environment as you cannot start a full browser inside the browser.



What you need is a server which does that for you. You could ether offer a HTTP endpoint (option 1) or expose your puppeteer Websocket (option 2):



Option 1: Provide a HTTP endpoint



For this option, you setup a server which handles the incoming request and runs the task (making a screenshot) for you:



server.js



const puppeteer = require('puppeteer');
const express = require('express');

const app = express();

app.get('/screenshot', async (req, res) =>
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(req.query.url); // URL is given by the "user" (your client-side application)
const screenshotBuffer = await page.screenshot(path: 'example.png');

// Respond with the image
res.writeHead(200,
'Content-Type': 'image/png',
'Content-Length': screenshotBuffer.length
);
res.end(screenshotBuffer);

await browser.close();
)

app.listen(4000);


Start the application with node server.js and you can now pass the URL to your server and get a screenshot back from your server: http://localhost:4000/screenshot?url=https://example.com/



The response from the server could then be used as as the source of an image element in your application.



Option 2: Exposing the puppeteer Websocket to the client



You could also control the browser (which runs on the server) from the client-side by by exposing the Websocket.



For that you need to expose the Websocket of your server like this:



server.js



const puppeteer = require('puppeteer');

(async () =>
const browser = await puppeteer.launch();
const browserWSEndpoint = browser.wsEndpoint();
browser.disconnect(); // Disconnect from the browser, but don't close it
console.log(browserWSEndpoint); // Communicate the Websocket URL to the client-side
// example output: ws://127.0.0.1:55620/devtools/browser/e62ec4c8-1f05-42a1-86ce-7b8dd3403f91
)();


Now you can control the browser (running on the server) form the client-side with a puppeteer bundle for the client. In this scenario you could now connect to the browser via puppeteer.connect and make a screenshot that way.



I would strongly recommend using option 1, as in option 2 you are fully exposing your running browser to the client. Even with option 1, you still need to handle user input validation, timeouts, navigation errors, etc.






share|improve this answer

























  • I went ahead and followed option 1. I got it working! Thank you! I didn't think something as easy as taking a screenshot of your browser requires a lot of steps. I also installed the cors library just to get past the cors error I was having.

    – NoobNewb
    Mar 7 at 18:11













1












1








1







Your React.js application runs on the client-side (in the browser). Puppeteer cannot run inside that environment as you cannot start a full browser inside the browser.



What you need is a server which does that for you. You could ether offer a HTTP endpoint (option 1) or expose your puppeteer Websocket (option 2):



Option 1: Provide a HTTP endpoint



For this option, you setup a server which handles the incoming request and runs the task (making a screenshot) for you:



server.js



const puppeteer = require('puppeteer');
const express = require('express');

const app = express();

app.get('/screenshot', async (req, res) =>
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(req.query.url); // URL is given by the "user" (your client-side application)
const screenshotBuffer = await page.screenshot(path: 'example.png');

// Respond with the image
res.writeHead(200,
'Content-Type': 'image/png',
'Content-Length': screenshotBuffer.length
);
res.end(screenshotBuffer);

await browser.close();
)

app.listen(4000);


Start the application with node server.js and you can now pass the URL to your server and get a screenshot back from your server: http://localhost:4000/screenshot?url=https://example.com/



The response from the server could then be used as as the source of an image element in your application.



Option 2: Exposing the puppeteer Websocket to the client



You could also control the browser (which runs on the server) from the client-side by by exposing the Websocket.



For that you need to expose the Websocket of your server like this:



server.js



const puppeteer = require('puppeteer');

(async () =>
const browser = await puppeteer.launch();
const browserWSEndpoint = browser.wsEndpoint();
browser.disconnect(); // Disconnect from the browser, but don't close it
console.log(browserWSEndpoint); // Communicate the Websocket URL to the client-side
// example output: ws://127.0.0.1:55620/devtools/browser/e62ec4c8-1f05-42a1-86ce-7b8dd3403f91
)();


Now you can control the browser (running on the server) form the client-side with a puppeteer bundle for the client. In this scenario you could now connect to the browser via puppeteer.connect and make a screenshot that way.



I would strongly recommend using option 1, as in option 2 you are fully exposing your running browser to the client. Even with option 1, you still need to handle user input validation, timeouts, navigation errors, etc.






share|improve this answer















Your React.js application runs on the client-side (in the browser). Puppeteer cannot run inside that environment as you cannot start a full browser inside the browser.



What you need is a server which does that for you. You could ether offer a HTTP endpoint (option 1) or expose your puppeteer Websocket (option 2):



Option 1: Provide a HTTP endpoint



For this option, you setup a server which handles the incoming request and runs the task (making a screenshot) for you:



server.js



const puppeteer = require('puppeteer');
const express = require('express');

const app = express();

app.get('/screenshot', async (req, res) =>
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(req.query.url); // URL is given by the "user" (your client-side application)
const screenshotBuffer = await page.screenshot(path: 'example.png');

// Respond with the image
res.writeHead(200,
'Content-Type': 'image/png',
'Content-Length': screenshotBuffer.length
);
res.end(screenshotBuffer);

await browser.close();
)

app.listen(4000);


Start the application with node server.js and you can now pass the URL to your server and get a screenshot back from your server: http://localhost:4000/screenshot?url=https://example.com/



The response from the server could then be used as as the source of an image element in your application.



Option 2: Exposing the puppeteer Websocket to the client



You could also control the browser (which runs on the server) from the client-side by by exposing the Websocket.



For that you need to expose the Websocket of your server like this:



server.js



const puppeteer = require('puppeteer');

(async () =>
const browser = await puppeteer.launch();
const browserWSEndpoint = browser.wsEndpoint();
browser.disconnect(); // Disconnect from the browser, but don't close it
console.log(browserWSEndpoint); // Communicate the Websocket URL to the client-side
// example output: ws://127.0.0.1:55620/devtools/browser/e62ec4c8-1f05-42a1-86ce-7b8dd3403f91
)();


Now you can control the browser (running on the server) form the client-side with a puppeteer bundle for the client. In this scenario you could now connect to the browser via puppeteer.connect and make a screenshot that way.



I would strongly recommend using option 1, as in option 2 you are fully exposing your running browser to the client. Even with option 1, you still need to handle user input validation, timeouts, navigation errors, etc.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 7 at 17:43

























answered Mar 7 at 17:23









Thomas DondorfThomas Dondorf

89259




89259












  • I went ahead and followed option 1. I got it working! Thank you! I didn't think something as easy as taking a screenshot of your browser requires a lot of steps. I also installed the cors library just to get past the cors error I was having.

    – NoobNewb
    Mar 7 at 18:11

















  • I went ahead and followed option 1. I got it working! Thank you! I didn't think something as easy as taking a screenshot of your browser requires a lot of steps. I also installed the cors library just to get past the cors error I was having.

    – NoobNewb
    Mar 7 at 18:11
















I went ahead and followed option 1. I got it working! Thank you! I didn't think something as easy as taking a screenshot of your browser requires a lot of steps. I also installed the cors library just to get past the cors error I was having.

– NoobNewb
Mar 7 at 18:11





I went ahead and followed option 1. I got it working! Thank you! I didn't think something as easy as taking a screenshot of your browser requires a lot of steps. I also installed the cors library just to get past the cors error I was having.

– NoobNewb
Mar 7 at 18:11



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55031823%2fhow-to-make-puppeteer-work-with-a-reactjs-app%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

1928 у кіно

Захаров Федір Захарович

Ель Греко