Gatsby - srr or browser to inject html (which is really vue) after webpack babel - static

I am using snipcart which looks at the static html document and looks for #snipcart element. You can put vue elements in there and the magic will be done on the snipcart.js side.
When using Gatsby, in order to edit the index.html file, you have to create a React file called html.js. In this file I can successfully add Snipcart and everything works. That is until I want to customize the cart and Snipcart uses vue for that. You have to add the vue items in between the #snipcart div.
snipcart-docs-customization
An example
<div hidden id="snipcart" data-api-key="<API_KEY>">
<component-to-override>
<div class="root">
{{ vue_variable.itemText }}
</div>
</component-to-override>
</div>
The problem is, webpack will throw an error if I add vue. This makes sense. So Gatsby has a couple of nice middleware type API's gatsby-ssr and gatsby-browser that might help this.
Looking at these API's I am still unsure how to do this. I need this code added to the index.html as Gatsby is rendering the static pages, at least I feel that is best.
Because Snipcart looks in the #snipcart divs innerHTML for vue formatted components, this is difficult because webpack wants to convert the vue, I do not want it converted.
How can I go about this?
Some useful links I have entertained:
Gatsby Lifecyle
Gatsby-ssr api
Gatsby-browser api
Snipcart customizing components

Related

How to implement/render JSX components?

I have standalone components like Header, Footer, etc. built in Storybook. The components are written in JSX. I have some react apps that consume those components by importing them, and rendering them with JSX notation.
Now we have a Drupal app which has a frontend written in Twig. I want to reuse the already built JSX components, to render them in Twig.
I am already creating a dist.js in plain js, compiled with webpack. So that the react apps can import the components, without having to parse JSX from the node_modules folder.
Now I would like to have the possibility to import the dist.js created with webpack (or the JSX files directly) into the Drupal app, and render single components (eg. Header, Footer, etc.). Everything in between should remain Twig.
I already tried to include the dist.js file with <script> tag, but then I didn't know how to trigger something that I can say, which component should be rendered and in which container it should be rendered.
I did a bit of research but what I found was just how to integrate an entire react app into Twig. But I already know this principle, and its not that what I want. I want just to render already written JSX components, in a mainly Twig written app. How can I accomplish that without rewriting the components in Twig?

Bootstrap component not working with react app

I have created a React Application and copied navbar from bootstrap component. I also added cdn files at index.html file. Also changed changed class to className but still but when run I get error with failed to compile and cursor is placed on data-toggle="colapse". upon removing this line it moves to next one. but its not working. .
working with bootstrap in react is not simple, it is easier to use React-bootstrap.
https://react-bootstrap.github.io/
you then just download the npm package and import the buttons and other options you want.
If you want to go about doing it this way, then you would need to use <button className="bootstrapclass">hello</button>
or specifically
<button className="btn btn-secondary">hello</button>
outside of that, there is no way to use bootstrap.
it is advisable that you share your code, so people can see what the mistake is.
The error was because of attaching cdn at outside the body. I resolved this by placing cdn of CSS and JS at just before the closing body tag.

Static site generator that renders React to HTML directly (no React in output)?

Can Gatsby or Jekyll or any other static site generators render a React-authored site into purely static HTML? I'm looking to host on S3/CloudFront or similar and also have little to no JS in the output.
Basically I'm looking to create a static website but would like to use React as development tool to take advantage of reusable UI components. Actual runtime interaction is minimal and can be done without React at runtime.
I looked at react-static which seems to be exactly what I'm looking for but the rendered html pages still reference and load the React library.
With my minimal needs I could probably roll my own thing to create each page as a separate React SPA and then use ReactDOMServerto render each to a static HTML file. I'm looking to see if there are simpler/better options.
You can use pupeteer to get the rendered html of any webpage, including SPA. Or use rendertron, which uses pupeteer underneath.
Another one is react-snap, which will crawl your web on build and create the html for each page.
With Gatsby, sure you can. Gatsby has a html.js that serves as a template for all generated pages. You can simply remove Gatsby's javascript from that html.
/* Generated html */
...
<body>
<div id="___gatsby">...</div>
<script src="/common.js"></script> <-- remove this
</body>
First copy the default html to your src:
cp .cache/default-html.js src/html.js
Then, edit this line:
/* src/html.js */
<body {...this.props.bodyAttributes}>
{this.props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: this.props.body }}
/>
- {this.props.postBodyComponents}
+ {process.env.NODE_ENV !== 'production' && this.props.postBodyComponents}
</body>
This ensures you can still make use of gatsby's hot reload in development, but generated htmls will not include React & webpack generated scripts.
A more meticulous approach would be to loop over postBodyComponents & only removes the script tag that link to common.js, but for most case I think it'll be fine.
This definitely defeats the purpose of Gatsby, which has its own convention & complex process just so it can generate a progressive web app. For your case, if you're not already familiar with Gatsby, maybe it'd be simpler to roll your own SSR. My answer is only to show whether it's possible with Gatsby or not.

External Hosted React JS with plain Javascript and HTML page

We have a common widget in each of our pages across multiple services, and we want to write a common client-side rendition code in ReactJS for this widget as an external hosted js, such that each of the pages can include this externally hosted JS in their pages to render the widget. But many of these pages are written in different JS frameworks (angular/inferno/typescript/etc) or even in plain vanilla JS. Now pardon me if this is an ignorant question, but I think that ReactJS code can be compiled into javascript using babel, and the bundled js file can then be directly included in any page using any framework(angular/typescript/etc). Is my assumption correct, or will such an approach lead to problems. Any other inputs?
PS: I am very new to any of these JS frameworks, and have only worked on small projects involving plain vanilla JS.
You can mount your react root node (typically <App/> ) in any html DOM node. This is what react-dom does by
render( <App />, document.getElementById("root"));
which would be a familiar line for you.
Now, coming to how to actually do this. I assume you are using create-react-app.
Run npm run build inside your project folder.
When it finishes, you will find a bunch of files inside your-project-folder/build, including
build/index.html
build/static/js, build/static/css, etc
Open the build/index.html file in a text editor and study it. I think you will be able to figure out the rest.

React index.html page separation using webpack

I am using react's create-react-app for my new application.
I am really getting confused to separate index.html page for client side and admin panel.
I have different functional flows and css files for both side.
So index.html file should be loaded based on router navigation.
Example:
http://example.com => should load client/index.html
http://example.com/admin => should load admin/index.html
Note: i have tried webpack's multiple entries method and webpack html plugin. But it only separates bundle files not html(while navigate).
Please help me out.
webpack just a module bundler, It doesn't control which page show, This should be done by router.
if it's single page, you can use react-router
if it's multi page, you can use express route
after using the below code to include the external scripts, I don't really want any additional html pages.
var $script = require("scriptjs")
$script("/myscript.js")

Resources