Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@HaNdTriX
Last active September 20, 2019 15:37
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 HaNdTriX/d05752a77219681e80298ef6cbb1f0df to your computer and use it in GitHub Desktop.
Save HaNdTriX/d05752a77219681e80298ef6cbb1f0df to your computer and use it in GitHub Desktop.
import React from 'react'
import ReactDOM from 'react-dom'
const isServer = typeof window === 'undefined'
const Context = React.createContext([])
export const HeadProvider = ({ head, children }) => (
<Context.Provider value={head}>
{children}
</Context.Provider>
)
const Head = ({ children }) => {
const head = React.useContext(Context)
if (isServer) {
head.push(
...React.Children.toArray(children)
)
return null
}
return ReactDOM.createPortal(children, document.head)
}
export default Head
@HaNdTriX
Copy link
Author

HaNdTriX commented Sep 20, 2019

⚠️ THIS IS JUST A PROOF OF CONCEPT

Advantages

  • thread save
  • accepts all possible elements
  • allows nesting
  • xss safe
  • minimal code
  • brings the wonderful world of react to the head
    • allows the use of real React Components
    • allows the use of hooks
    • allows the use of hocs

Usage

import Head from 'next-head'

const SomeComponent = () => (
  <>
    <Head>
      <title>Hello World!</title>
    </Head>
    <h1>Hello World!</h1>
  </>
)

Server rendering setup

const renderOnTheServer = () => {
  const headElements = []

  const body = ReactDOMServer.renderToString(
    <HeadProvider value={headElements}>
      <App />
    </HeadProvider>
  )

  const head = ReactDOMServer.renderToString(headElements)

  return { head, body }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment