I'm looking for a way to embed a browser in a React application with the ability to add onclick events on search page selectors. I'm wondering if I could use Electron or NW.js. Does anybody have an idea?
I started with iframes at first, but here's the problem with cross domain. Then I thought about puppeteer and png rendering with positioning, but it's not very intuitive. And recently I found threads about Electron and NW.js
You haven't really explained what you mean by "embed a browser in a React app". A browser is an executable that renders HTML/CSS/JS. React is a JS library that runs in a browser.
I'm not sure what you are trying to do. Maybe embed a different website on the same page? In which case, yes you would use an iframe. There are many security contraints put in place, for good reason.
Electron is a Node.js script that spawns a chromium browser that can communicate with a separate Node process.
NW.js is a modified Chromium browser with Node.js built in.
Both of them are going to have security restrictions similar to a normal browser. NW.js has some additional options you could try (again, not sure what you actually want). But there are still server-side restrictions for CORS that you'd need to deal with no matter what.
I think the real solution here is for you to re-evaluate what your goal is, and then find a better solution to it.
More on NW.js/Electron at:
https://xpda.net
Related
Obviously I wouldn't be able to utilize IPC or persist data but I would like to use Chrome directly to build some UI stuff. If I like the look I thought I could just build up an ElectronJS app around it to handle the actual window stuff. Is that possible or is that asking for problems?
Of course. You can package the react web application as the static resource and then load in electron browse window.
I have this project where I have to code a website and ios and android apps.
I have to do this with a very limited team (basically myself). So I want to share as much code between those platforms, to avoid maintaining different codebases as much as possible.
I have come to consider flutter : the logic (and interaction with the backend) in dart can be compiled to both ios and android, and to javascript for the web site to call. I also like how the UI is built using flutter.
For the web site, I know there is flutter web that can be used to do a web app, but I want my website to feel like a web site more than a single page app. I have thought about using React+Gatsby to do the website's ui, while calling the dart compiled js for the logic. That would enable high page loading speed, good seo, while keeping the interactivity of a react app and the single codebase logic through dart to js compilation.
I am wondering if this seems like a good approach to you, and if not, how you would do it.
In this approach, I am wondering if it would be possible to embedded flutter web widgets inside of react js components, always in a concern of maintaining as low platform specific code as possible. I have not found any other way of doing this than embedding them into iframes, which does not seem like a good idea, or does it ?
Update
Flutter Web is now available in a stable version for production.
Below answer is relevant back to the time when question was asked.
Flutter Web not recommended
At the current date, I would recommend not to use Flutter Web for production as it's in Beta. The Flutter Team is still working on improving quality, performance and browser compatibility. You must be cautious about using it as you may run into bugs and some other complications.
Also, I believe that the community support for Flutter Web might be on a lower side as it's pretty new.
Limited browser support
Another factor which bugs me is that the Flutter web apps can run on limited browsers as of now which would affect the reach to your user base:
Chrome (mobile & desktop)
Safari (mobile & desktop)
Edge (mobile & desktop)
Firefox (desktop)
What would I prefer?
Well, although it might be a hassle to handle different codebases for mobile and web platforms, I would still prefer to stick with React JS as it's much stable with better browser & community support as opposed to Flutter Web.
Good luck with your app! :)
I am unaware of how to use Flutter widgets inside a React app. But to address your other concerns,
So I want to share as much code between those platforms, to avoid maintaining different codebases as much as possible.
Given no other restrictions, this leads to a single Flutter app for both web and native. For a team as small as three we still found it easier than having multiple projects.
The key factor in merging our initial projects to one was the notion of mobile browsers. In a mobile browser you website should reduce itself to the look of your mobile app, unless they have different purposes. And this automatically happens with Flutter projects if you derive your layout breakpoints from screen size. Otherwise you would code your same narrow design twice: in Flutter for native apps and in React for web.
Same goes for native apps for tablets in landscape mode. They call for a layout that resembles your desktop browser version, and you automatically get it with Flutter.
Also in web version you may have more tools than in a native app, just because your screen allows it. Naturally, you would code this logic in JS. But then you get an order to migrate this to native apps. Would you then replace your JS logic with Dart logic compiled to JS and embedded into frames? This is a messy road.
Lastly, think of Mac, Linux and Windows platforms that will come to Flutter soon. Should you ever need a desktop native app, you would want the same layout as with web.
I want my website to feel like a web site more than a single page app.
The difference in feeling between a website and a single page app lies mostly in state management and URL handling. You may do the following to reduce it:
Introduce URLs for your pages. By default, in Flutter every piece of action can happen under a single URL of example.com/#/. The window then feels fragile as there is no URL to copy and get back to. Flutter's Router API, released in Oct 2020, allows you to generate URLs on any change in your app's state and parse the state back from URL. If you do it right, then everything on your screen becomes a function of the URL, just like in traditional websites.
Use url_stragegy package for your URLs to be example.com/path rather than example.com/#/path which immediately feels fake.
I have not found any other way of doing this than embedding them into iframes, which does not seem like a good idea, or does it ?
No, it does not. Mostly because you get too narrow a channel of communication of messages between JS windows. How would you listen to Flutter's BLoC's stream in another frame? It would take too much boilerplate code. Also I cannot think of easy debugging process.
To me, Flutter Web still has drawbacks:
It takes awhile to load.
Many specific JS APIs are not implemented yet.
Many services you integrate with may not have Dart SDK, while having JS SDK. For instance, I struggled to get Ably working.
No search engine optimization.
You cannot use em as a screen unit, so scaling elements may get tricky.
Still with limited resources a single codebase outweights everything else.
To be clear, my team has been working on a web+native project the whole 2021. It now has passed most of the testing, but not yet released. For a sense of scale, it is a marketplace of 40+ screens.
I have a request from a client to implement deep linking in our React application whereby clicking a link will take them directly into the installed app (potentially to a certain point but not sure on that yet).
To my understanding react-native and react-navigation both handle this as part of a feature set within "Linking" that they offer. However it seems excessive to import a framework just for deep linking (perhaps not though).
After googling I can only really find references to deep linking on react-native or react-navigation.
What is my best course of action?
Let's get to some basics first, then it will be clear.
In modern SPA's, say with React, it's common for the SPA to handle navigation itself. You need to use browser's history API. It's because your SPA is just a single index.html with bunch of js code, so it sort of virtual, every page is constructed by your app. In order to not reinvent a wheel, its easier to use some library for that, say react-router-dom.
But then everything works as expected, and you have deployed your app. When user wants to get some deep page, say, https://my-awesome-app.com/deep/page/1, browser will just send a request to a server, asking: "Please, server, give me a page 1.html, in folder page, in folder deep". But server doesn't have that file, because it has literally one index.html, because its a SPA application. Then we need to tell the server to re-write all deep routes to index html, here is an example for my app hosted on Netlify:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
When user will ask for that page, server will 'redirect' that request to the index.html and my react-router-dom will figure out which 'PageComponent' to render based on that path.
So, you can implement routing in your app yourself, probably using browser's History API, but I guess it might be easier to use library. But it's your call.
On the other hand if your app is not an SPA, the story might be different, because say in NextJS routing is implemented in framework itself, and if used deep linking would require different setup depending on how app is deployed.
Deep-linking is handled largely by Apple and Google server-side
https://www.adjust.com/blog/dive-into-deeplinking/
React-native provides extended functionality for deep-linking within mobile apps but normal web-applications there is no need to implement it there. Use universal links or Google specific links as standard linking within your web app to enable deep linking
In an article I read that
React uses server-side rendering.
But in another articles I came across this:
Client-Side-Rendering is a relatively new approach to rendering
websites, and it didn't really become popular until JavaScript
libraries started incorporating it into their style of development.
Some notable examples are Vue.js and React.js
Now Which statement is correct?
When I use create-react-app and run npm start, it seems to me that React uses the Client-Side-Rendering. isn't it?
It’s client side. But React, like some other client side libraries, can be used on the server to prerender it with node, usually for SEO.
Out of the box it renders on the client side.
But, if you have a requirement to render pages on a server, you can achieve this with:
Next.js or
Hypernova or any other tool (there is a bunch of them nowadays!)
Note, that SSR will require a bit more experience than a regular React app.
The main goal of this approach is to allow search engine robots crawl information form web pages(SEO).
create-react-app uses client side rendering by default. There are some tools like next js and gatsby js which pre-render pages on the server side. You can also do Server Side Rendering from scratch.
A few years on from the last answer, it is now quite difficult to implement a client-only React app - serving it on Node is trivial and absolutely what it expects, trying to use it as a client library with other server-side support is more of a challenge and documentation about how to do this is patchy and much of it out of date.
I have an angular app currently in Electron. (It was built by someone else) I would like to run this in my browser (possibly converting it to a Progressive Web App). Is this possible? If so how?
A short summary from some of my own experience doing something similar. In my case it was possible but this might not always be true. Hope this helps.
Find and assess the app's dependencies on the Electron api - try searching for require('electron') or more likely in Angular, ngxElectron or another Angular Electron api wrapper, fixing or changing the app so that it no longer depends on Electron.
Do a search for Electron API keywords and usages and decide how to handle them. Examples where the app might use Electron - the Electron menu, clipboard, BrowserView, or more behind-the-scenes the app might use IPC.
The app might reference the Node api since Node is relatively easy to mix in to your app in Electron, and this will be a problem that needs to be fixed. Search for Node api references.
Some apps have native dependencies outside of Electron, you'll need to find any such API's and decide how to handle them.
The size of work (and even if it's possible at all) will depend on the functionality the app itself provides and the extent of native features required, the extent of dependency on Electron features, dependencies on Node.
For example, within Electron, developers have more control over the browser than usual, and can choose to switch off normal web security features. Cross site scripting (CORS, etc) or other security issues might crop up when you move the app to the browser. Take a look at the options passed when BrowserWindows are created. If the app has exotic settings these might necessitate architecture changes.
You need to decide whether the app still needs to work in Electron after porting (this might be possible but can make things complicated)
If the app should still run in Electron, you'll need to decide a strategy for how to handle this (for example, if statements checking for Electron, or another strategy).