finsweet/developer-starter

How to use this with devlink?

chrisle opened this issue · 4 comments

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.

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"]
  }
}

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.

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.

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?