Created
January 22, 2021 03:18
-
-
Save crutchcorn/21dffe537a46a5d27261cb75a3b9a39c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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