Skip to content

Commit

Permalink
Merge branch 'master' of github.com:supertokens/blog into cookies-vs-…
Browse files Browse the repository at this point in the history
…localstorage
  • Loading branch information
Chakravarthy7102 committed Sep 11, 2023
2 parents 6a48374 + 28519b4 commit cb65530
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
title: Speed up your web development time by integrating Webflow into a React application
date: "2020-12-10"
description: "Writing JSX to build pixel perfect UI elements can be very time consuming and frustrating. Learn how react engineers can inject complex elements / React components into a Webflow generated HTML page."
cover: "speed-up-your-web-development-time-by-integrating-webflow-into-a-react-application.png"
category: "programming"
author: "Rishabh Poddar"
---

Writing JSX to build pixel perfect UI elements can be very time consuming and frustrating. I’m talking about the process of figuring out the exact padding, margin, flexbox, width, height etc to match the required design spec. As React engineers, our time is most well spent on what we can do uniquely - write state management logic, API calls, error handling, component architecture, animations and building complex components that require lots of user interactions.

The aim of this blog post is to provide a methodology using which designers can build the simpler UI HTML elements using Webflow and React engineers can inject complex elements / React components into the generated HTML page. This works best for sites that have less user specific / user generated content - like several b2b sites.

Note: _For those who do not know about Webflow, it’s a tool that let’s designers design the UI, and it emits fully functional HTML code._

## Technical guide

As an example, let’s consider a webpage where most of the body is generated using Webflow apart from the header and the footer - which are arbitrarily complex react components.

### Creating empty divs

We start by assuming that we have already generated the HTML, JS and CSS files using webflow. The HTML file contains the head and body tags as usual.

We want to insert our React `header` component at the top of the body, so we add an empty `<div>` element with a unique id:

```tsx
<head>...</head>
<body>
<div id="webflow-header"></div>
... HTML generated by webflow
</body>
```

As we will see later, the `header` component will be rendered inside the div above. We will get the ref of the div using the id `“webflow-header”`

We then want to make place for the footer, which should go right before the closing body tag:

```tsx
<head>...</head>
<body>
<div id="webflow-header"></div>
... HTML generated by webflow
<div id="webflow-footer"></div>
</body>
```

We also want to create a div where the whole react app will load in. Think of this as an entrypoint for the react app. From here, it will render the `header` and `footer` component into the two divs created above. We will do this using the [createPortal](https://react.dev/reference/react-dom/createPortal) function provided by React (as we will see later):


```tsx
<head>...</head>
<body>
<div id="webflow-header"></div>
... HTML generated by webflow
<div id="webflow-footer"></div>
<div id="react-root"></div>
</body>
```

### Adding the React bundle

Just like in a normal `react` app, we need to add the `<script>` tag that will load the bundle and run the React app:

```tsx
<script src = "bundle.js"></script >
```

### Loading the React app

We want to load the react app in the div with the ID `“react-root”`. This will load the `root` component of your react app, which can then load the `header` and `footer` react component in their respective div tags. The react app can also be used for any other operation like analytics:

```tsx
ReactDOM.render((
<Router />
), document.getElementById("react-root"));
```

### Find the header and footer div nodes from the React app

In order to inject the `header` and `footer` components into their divs, we need to first get a reference to them. We do so using the `document.getElementById` function in the `root` component of the react app

```tsx
this.headerDiv = document.getElementById("webflow-header");
this.footerDiv = document.getElementById("webflow-footer");
```

In pages where the divs have not been inserted, the value for `this.headerDiv` and `this.footerDiv` will be null. So we need to remember to do a null check before using them.


### The render function

In order to inject the components, we have to call the `createPortal` function from inside the `render` function. This function takes two arguments:

- The react component to render
- The DOM node reference (in our example, it’s `this.headerDiv` or `this.footerDiv`)

```tsx
render() {
let result = [];
if (this.headerDiv) {
result.push(ReactDOM.createPortal(<Header />, this.headerDiv));
}

if (this.footerDiv) {
result.push(ReactDOM.createPortal(<Footer />, this.footerDiv))
}
return result;
}
```

- Notice that we check that `footerDiv` and `headerDiv` are not falsy value - which will be the case when the div elements are not added into the webflow html page.
- We create an array of JSX elements to inject more than one react component. If the number of components to inject is just one, then we can simply do return `ReactDOM.createPortal(<Header />, this.headerDiv)`

We have successfully added react components to a webflow generated HTML page.


### However…

Since the injection of the components happen after the react bundle is downloaded and run, the user first sees the HTML that’s generated using Webflow, and then sees a jitter as the react components are injected (which occupy their own height and width). Unfortunately, this jitter is quite noticeable.

We can fix this by setting the body tag’s CSS to have `display: none` initially, and then after the components have been injected, we can set the display to block (in the `componentDidMount` or `useEffect` function). This way, the experience for the user is the same as if the whole page is made using React.

So in the `componentDidMount` / `useEffect` function, we should do the following

```tsx
let body = document.getElementsByTagName("body")[0];
if (body !== null) {
body.style.display = "block";
}
```
The above would prevent the jitter and provide a seamless experience for the user.

## In Conclusion

We saw how we can inject components into an existing HTML page generated via Webflow using the `ReactDOM.createPortal` function.

This method allows for quicker development of relatively static web pages saving you money. As a reference, we at [SuperTokens](https://supertokens.com/) use this method. Our home page is made completely using Webflow, excepting for the header and footer - which are injected using the method shown above.
12 changes: 0 additions & 12 deletions src/blog-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,6 @@ module.exports = [
cover: "implementing-a-forgot-password-flow.png"
},
},
{
fields: {
slug: "/speed-up-your-web-development-time-by-integrating-webflow-into-a-react-application",
},
frontmatter: {
title: "Speed up your web development time by integrating Webflow into a React application",
description: "Writing JSX to build pixel perfect UI elements can be very time consuming and frustrating. Learn how react engineers can inject complex elements / React components into a Webflow generated HTML page.",
category: "programming",
date: "December 10, 2020",
cover: "speed-up-your-web-development-time-by-integrating-webflow-into-a-react-application.png"
}
},
{
fields: {
url: "https://www.youtube.com/watch?v=6Vzit514kZY&list=PLE5w09cAseKTIFCImkqFbSeYMHPzW7M_f&index=17",
Expand Down

0 comments on commit cb65530

Please sign in to comment.