finsweet / developer-starter

Developer starter template for Finsweet projects.
https://www.finsweet.com/
180 stars 61 forks source link

How to use this with devlink? #48

Open chrisle opened 1 year ago

chrisle commented 1 year ago

I'm wondering if there's a way to use this with DevLink.

My use case is I would like to try using Webflow to develop the frontend but bring in React components into Webflow using this repository.

chrisle commented 1 year ago

I did manage to get a plain React to work this way...

Screenshot 2023-09-02 at 11 50 44 AM
// src/utils/greetReact.tsx

/* eslint-disable no-console */
import { getPublishDate } from '@finsweet/ts-utils';
import { createRoot } from 'react-dom/client';

/**
 * Test React component.
 */
export function GreetReact(props: { name: string }) {
  const { name } = props;
  return <h1>Hello {name}!</h1>;
}

/**
 * Greets the user by printing a message in the console.
 * @param name The user's name.
 */
export const greetUser = (name: string) => {
  const publishDate = getPublishDate();
  console.log(
    `This site was last published on ${publishDate?.toLocaleDateString('en-US', {
      year: 'numeric',
      month: 'long',
      day: '2-digit',
    })}.`
  );

  const reactElement = document.querySelector('[data-element="greet-react"]');
  if (!reactElement) return;
  const reactRoot = createRoot(reactElement);
  reactRoot.render(<GreetReact name={name}/>);
};
// src/index.ts
import { greetUser } from '$utils/greetReact';

window.Webflow ||= [];
window.Webflow.push(() => {
  greetUser('John Doe');
});
/* tsconfig.json */
{
  "extends": "@finsweet/tsconfig",
  "compilerOptions": {
    "jsx": "react-jsx",
    "rootDir": ".",
    "baseUrl": "./",
    "paths": {
      "$utils/*": ["src/utils/*"]
    },
    "types": ["@finsweet/ts-utils"]
  }
}
alexiglesias93 commented 1 year ago

Hey @chrisle! You already managed to successfully mount the react components on your Webflow site, so you're almost there. All you need to do now is install the Webflow SDK in your project and start syncing with DevLink. DevLink will import all the components into a folder of your repository and you'll be able to import and use them in your code just like you used the GreetReact component in your example.

chrisle commented 1 year ago

So i did manage to modify it more to get Devlink in but I did run into something I haven't been able to solve.

// src/utils/greetReact.tsx

/* eslint-disable no-console */
import { getPublishDate } from '@finsweet/ts-utils';
import { createRoot } from 'react-dom/client';
import { useState } from 'react';

/**
 * Test React component.
 */
export function GreetReact(props: { name: string }) {
  const [ name, setName ] = useState(props.name);
  return <h1>Hello {name}!</h1>;
}

/**
 * Greets the user by printing a message in the console.
 * @param name The user's name.
 */
export const greetUser = (name: string) => {
  const publishDate = getPublishDate();
  console.log(
    `This site was last published on ${publishDate?.toLocaleDateString('en-US', {
      year: 'numeric',
      month: 'long',
      day: '2-digit',
    })}.`
  );

  const reactElement = document.querySelector('[data-element="greet-react"]');
  if (!reactElement) return;
  const reactRoot = createRoot(reactElement);
  reactRoot.render(<GreetReact name={name}/>);
};

I end up getting:

jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2 jQuery.Deferred exception: Cannot read properties of null (reading 'useState') TypeError: Cannot read properties of null (reading 'useState')
    at Object.useState (http://localhost:3000/index.js:1102:31)
    at GreetReact (http://localhost:3000/index.js:24435:52)
    at loadComponents (http://localhost:3000/index.js:24465:108)
    at http://localhost:3000/index.js:24473:5
    at Tv (https://uploads-ssl.webflow.com/64eb83656f778a04b8b8c0f3/js/webflow.5a507b8f9.js:22:2351)
    at Array.forEach (<anonymous>)
    at bv.exports.e.each.e.forEach (https://uploads-ssl.webflow.com/64eb83656f778a04b8b8c0f3/js/webflow.5a507b8f9.js:10:20519)
    at ot.ready (https://uploads-ssl.webflow.com/64eb83656f778a04b8b8c0f3/js/webflow.5a507b8f9.js:22:2301)
    at e (https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2:30005)
    at t (https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2:30307) undefined
S.Deferred.exceptionHook @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
t @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
setTimeout (async)
(anonymous) @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
c @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
fireWith @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
fire @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
c @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
fireWith @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
ready @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2
B @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2 Uncaught TypeError: Cannot read properties of null (reading 'useState')
    at Object.useState (react.development.js:1622:21)
    at GreetReact (GreetReact.tsx:5:37)
    at loadComponents (loadComponents.tsx:27:22)
    at index.ts:5:3
    at Tv (webflow.5a507b8f9.js:22:2351)
    at Array.forEach (<anonymous>)
    at bv.exports.e.each.e.forEach (webflow.5a507b8f9.js:10:20519)
    at ot.ready (webflow.5a507b8f9.js:22:2301)
    at e (jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2:30005)
    at t (jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2:30307)

I understand what that means, I just couldn't figure out why. I'm not sure where JQuery.Deferred was coming into play there and if somehow it was calling the hook in a way I'm not expecting.

alexiglesias93 commented 1 year ago

So i did manage to modify it more to get Devlink in but I did run into something I haven't been able to solve.


// src/utils/greetReact.tsx

/* eslint-disable no-console */

import { getPublishDate } from '@finsweet/ts-utils';

import { createRoot } from 'react-dom/client';

import { useState } from 'react';

/**

 * Test React component.

 */

export function GreetReact(props: { name: string }) {

  const [ name, setName ] = useState(props.name);

  return <h1>Hello {name}!</h1>;

}

/**

 * Greets the user by printing a message in the console.

 * @param name The user's name.

 */

export const greetUser = (name: string) => {

  const publishDate = getPublishDate();

  console.log(

    `This site was last published on ${publishDate?.toLocaleDateString('en-US', {

      year: 'numeric',

      month: 'long',

      day: '2-digit',

    })}.`

  );

  const reactElement = document.querySelector('[data-element="greet-react"]');

  if (!reactElement) return;

  const reactRoot = createRoot(reactElement);

  reactRoot.render(<GreetReact name={name}/>);

};

I end up getting:


jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2 jQuery.Deferred exception: Cannot read properties of null (reading 'useState') TypeError: Cannot read properties of null (reading 'useState')

    at Object.useState (http://localhost:3000/index.js:1102:31)

    at GreetReact (http://localhost:3000/index.js:24435:52)

    at loadComponents (http://localhost:3000/index.js:24465:108)

    at http://localhost:3000/index.js:24473:5

    at Tv (https://uploads-ssl.webflow.com/64eb83656f778a04b8b8c0f3/js/webflow.5a507b8f9.js:22:2351)

    at Array.forEach (<anonymous>)

    at bv.exports.e.each.e.forEach (https://uploads-ssl.webflow.com/64eb83656f778a04b8b8c0f3/js/webflow.5a507b8f9.js:10:20519)

    at ot.ready (https://uploads-ssl.webflow.com/64eb83656f778a04b8b8c0f3/js/webflow.5a507b8f9.js:22:2301)

    at e (https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2:30005)

    at t (https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2:30307) undefined

S.Deferred.exceptionHook @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

t @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

setTimeout (async)

(anonymous) @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

c @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

fireWith @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

fire @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

c @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

fireWith @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

ready @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

B @ jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2

jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2 Uncaught TypeError: Cannot read properties of null (reading 'useState')

    at Object.useState (react.development.js:1622:21)

    at GreetReact (GreetReact.tsx:5:37)

    at loadComponents (loadComponents.tsx:27:22)

    at index.ts:5:3

    at Tv (webflow.5a507b8f9.js:22:2351)

    at Array.forEach (<anonymous>)

    at bv.exports.e.each.e.forEach (webflow.5a507b8f9.js:10:20519)

    at ot.ready (webflow.5a507b8f9.js:22:2301)

    at e (jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2:30005)

    at t (jquery-3.5.1.min.dc5e7f18c8.js?site=64eb83656f778a04b8b8c0f3:2:30307)

I understand what that means, I just couldn't figure out why. I'm not sure where JQuery.Deferred was coming into play there and if somehow it was calling the hook in a way I'm not expecting.

I've seen this error happen in the past when the site was being loaded under Editor mode, is that the case? Have you tried opening the site in Incognito?