Skip to content

Instantly share code, notes, and snippets.

@crutchcorn
Created January 22, 2021 03:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crutchcorn/21dffe537a46a5d27261cb75a3b9a39c to your computer and use it in GitHub Desktop.
Save crutchcorn/21dffe537a46a5d27261cb75a3b9a39c to your computer and use it in GitHub Desktop.
/**
* This is a demonstration Gist outlining how to define custom elements and access process environment variables.
* Both of which are required for setting up shoelace
* @see https://shoelace.style/
*
* Keep in mind that these components will not be present during the initial SSR paint, as the custom element definition
* occurs on the client only (due to limitations in NextJS)
*
* This method of custom element definition was most recently used in this repo:
* @see https://github.com/Ethan-Hill/Nexify
*/
import * as React from 'react';
import {
setAssetPath,
SlButton,
} from "@shoelace-style/shoelace";
function ClientBeforeRender({URL}) {
const elsDefined = useRef(false);
/**
* Must use `useLayoutEffect`. This is because it runs before the initial render
*
* If you use `useEffect` instead, the props will be set of the custom components in the initial render,
* then the custom element will be defined, potentially wiping out the props, and you'll have un-expected render
* behavior.
*/
React.useLayoutEffect(() => {
// Intentionally using `.current` inside effect, do not use `useState` here - will trigger re-render
if (elsDefined.current) {
return;
}
setAssetPath(`${URL}/static/static`);
customElements.define("sl-button", SlButton);
elsDefined.current = true;
}, [URL, elsDefined])
return null;
}
function App({URL}) {
return (
<div>
{null /* You will get errors thrown your way if you don't use process.browser because of */}
{null /* the `useLayoutEffect` setup. This allows you to run this code just on the client */}
{process.browser && <CustomEls URL={URL} />}
{null /* ... */}
</div>
)
}
App.getInitialProps = async (context) => {
// This process env is inaccessible from client, and thus must be used in `getInitialProps`
const URL = process.env.NEXTAUTH_URL;
return {
URL,
};
};
export default App;
/**
* This is a demonstration Gist outlining how to define custom elements and access process environment variables.
* Both of which are required for setting up shoelace
* @see https://shoelace.style/
*
* Keep in mind that these components will not be present during the initial SSR paint, as the custom element definition
* occurs on the client only (due to limitations in NextJS)
*
* This method of custom element definition was most recently used in this repo:
* @see https://github.com/Ethan-Hill/Nexify
*/
import * as React from 'react';
import {
setAssetPath,
SlButton,
} from "@shoelace-style/shoelace";
function ClientBeforeRender({URL}) {
const elsDefined = useRef(false);
/**
* Must use `useLayoutEffect`. This is because it runs before the initial render
*
* If you use `useEffect` instead, the props will be set of the custom components in the initial render,
* then the custom element will be defined, potentially wiping out the props, and you'll have un-expected render
* behavior.
*/
React.useLayoutEffect(() => {
// Intentionally using `.current` inside effect, do not use `useState` here - will trigger re-render
if (elsDefined.current) {
return;
}
setAssetPath(`${URL}/static/static`);
customElements.define("sl-button", SlButton);
elsDefined.current = true;
}, [URL, elsDefined])
return null;
}
function App({URL}) {
return (
<div>
{null /* You will get errors thrown your way if you don't use process.browser because of */}
{null /* the `useLayoutEffect` setup. This allows you to run this code just on the client */}
{process.browser && <CustomEls URL={URL} />}
{null /* ... */}
</div>
)
}
App.getInitialProps = async (context) => {
// This process env is inaccessible from client, and thus must be used in `getInitialProps`
const URL = process.env.NEXTAUTH_URL;
return {
URL,
};
};
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment