dm3-org / dm3

The dm3 protocol | New standard of web3 messaging | Decentralized ENS-based registry | Secure end-to-end encryption | Easy dApp integration
https://dm3.network
BSD 2-Clause "Simplified" License
73 stars 15 forks source link

Webflow integration #904

Open steffenkux opened 4 months ago

steffenkux commented 4 months ago

Requirements

Build a demo project in webflow, which integrates the dm3-messenger-widget. The name of the project is dm3-demo-integration-webflow.

The goal is, to fully integrate dm3 in webflow applications and provide an example (this project), of how to do it.

Tasks

Bhupesh-mfsi commented 4 months ago

According to webflow, we can't use NPM packages directly in the webflow. Indirectly there are 2 ways to do it :-

  1. We can use DM3 widget via CDN link by hosting the DM3 widget code somewhere.

  2. Putting the entire code of DM3 dist folder inside webflow.

Now 2nd option is not possible because its custom code has a limit of only 10000 characters. If we go with the 1st option then also there is a problem that we have multiple files & componenets in our widget. So we can't add CDN links for each and every file in the custom code of webflow.

I tried bundling the add with parcel bundler which creates single output file which we can use via CDN link and may be that works. But it didn't worked.

NOTE : How typescript will work in webflow that solution I haven't found yet.

For more details checkout this discussion on webflow : https://discourse.webflow.com/t/running-a-js-package-through-npm-on-webflow/116041/7

To use normal React code snippet in webflow, we can do like this. This is a React.js example code for webflow.

In webflow project navigate to -> pages -> Static pages -> Home -> settings -> Custom code -> Body tag

<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
<script src="https://unpkg.com/babel-core@5.8.38/browser.js"></script>

<script type="text/babel">
class Todo extends React.Component {
    constructor() {
    super();
    this.state = { 
      todo: [
        { value: 'new todo item 1', completed: false },
        { value: 'new todo item 2', completed: false },
        { value: 'new todo item 3', completed: false },
      ],
      completed: [],
      value: '',
    };

    this.handleChange = this.handleChange.bind(this);
  }

  createTodo() {
    if (this.state.value !== '') {
      const todos = this.state.todo;
      const updatedTodos = todos.concat({ value: this.state.value, completed: false });
      this.setState({ todo: updatedTodos, value: '' });
    } else {
      return null;
    }
  }

  toggleComplete(todo, i) {
    // add todo to completed todos
    const completedItems = this.state.completed.concat(todo);
    this.setState({ completed: completedItems });

    // remove completed todo from todos
    const todos = this.state.todo;
    todos.splice(i, 1);
    this.setState({ todo: todos });
  }

  deleteComplete(i) {
    const completedItems = this.state.completed;
    completedItems.splice(i, 1);
    this.setState({ completed: completedItems });
  }

  handleChange(event) {
    this.setState({ value: event.target.value });
  }

  renderTodos() {
    if (this.state.todo.length !== 0) {
      const todoItems = this.state.todo.map((todo, i) => {
        return (
          <div className="todo__list__item" key={i}>
             <div className="todo__card">
                <div className="todo__card__content">{todo.value}</div>
                <div className="todo__btn" onClick={this.toggleComplete.bind(this, todo, i)}></div>
             </div>
          </div>
        );
      });
      return todoItems;
    } else {
      return <div className="empty-state">Start by creating a new task!</div>
    }
  }

  renderCompleted() {
    if (this.state.completed.length !== 0) {
      const completedItems = this.state.completed.map((todo, i) => {
        return (
          <div className="todo__list__item" key={i}>
             <div className="todo__card">
                <div className="todo__card__content">{todo.value}</div>
                <div className="todo__btn todo__btn--delete" onClick={this.deleteComplete.bind(this, i)}></div>
             </div>
          </div>
        );
      });
      return completedItems;
    } else {
      return <div className="empty-state">Complete a task!</div>;
    }
  }

  render() {
    return (
      <div className="todo-app">
         <div className="todo">
            <div className="todo__input">
               <input type="text" 
                      className="w-input todo__input__field"
                      placeholder="What do you need to-do?"
                      value={this.state.value}
                      onChange={this.handleChange} />
               <div className="todo__input__btn"
                       onClick={() => this.createTodo()}
                       type="text">+</div>
            </div>
            <div className="todo__main">
               <div className="title">Todo</div>
               <div className="todo__list">
                 {this.renderTodos()}
               </div>
               <div className="title title--margin-top">Completed</div>
               <div className="todo__list">
                 {this.renderCompleted()}
               </div>
            </div>
         </div>
      </div>
    );
  }
};

ReactDOM.render(<Todo />, document.getElementById('app'));
</script>

Now if you publish the website and open it you will see the react code works. It means react code works in webflow.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

Now to use the DM3 widget in webflow, following code has been tested which doesn't works and gives error cannot use export in browser, if cjs directory is used instead of esm then also same error is thrown. The code snippet used is

<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/typescript/5.4.5/typescript.js"></script>
<script src="https://unpkg.com/babel-core@5.8.38/browser.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@dm3-org/dm3-messenger-widget@1.2.0/lib/esm/widget.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@dm3-org/dm3-messenger-widget@1.2.0/lib/esm/widget.js" type="text/javascript" crossorigin="anonymous"></script>
<script type="module">

import { DM3, DM3Configuration } from '@dm3-org/dm3-messenger-widget';

export function Home() {

  const props: DM3Configuration = {
    userEnsSubdomain: ".beta-user.dm3.eth",
    addressEnsSubdomain: ".beta-addr.dm3.eth",
    resolverBackendUrl: "http://134.122.95.165/resolver-handler",
    profileBaseUrl: "http://134.122.95.165/api",
    defaultDeliveryService: "beta-ds.dm3.eth",
    backendUrl: "http://134.122.95.165/api",
    chainId: "11155111",
    resolverAddress: "0xae6646c22D8eE6479eE0a39Bf63B9bD9e57bAD9d",
    defaultServiceUrl: "http://134.122.95.165/api",
    ethereumProvider: "https://eth-sepolia.g.alchemy.com/v2/",
    walletConnectProjectId: "27b3e102adae76b4d4902a035da435e7",
    defaultContact: 'contact.dm3.eth',
    showAlways: true,
    showContacts: true
  }

    render() {
    return (
      <div>
        <main>
          <DM3 {...props} />
        </main>
      </div>
    )
  }
}

ReactDOM.render(<Home/>, document.getElementById('app'));
</script>

It doesn't works