Git Product home page Git Product logo

Comments (5)

alfredosalzillo avatar alfredosalzillo commented on July 27, 2024 4

@siamahnaf I have found a solution.

In the library:

// src/style-inject.js
export default function styleInject(css, id, { insertAt } = {}) {
  if (!css) return
  if (typeof document === 'undefined') {
    globalThis.ssrCss = globalThis.ssrCss || []
    globalThis.ssrCss.push({ css, id })

    return
  }

  if (document.getElementById(id)) return

  const head = document.head || document.getElementsByTagName('head')[0]
  const style = document.createElement('style')
  style.id = id
  style.type = 'text/css'

  if (insertAt === 'top') {
    if (head.firstChild) {
      head.insertBefore(style, head.firstChild)
    } else {
      head.appendChild(style)
    }
  } else {
    head.appendChild(style)
  }

  if (style.styleSheet) {
    style.styleSheet.cssText = css
  } else {
    style.appendChild(document.createTextNode(css))
  }
}
// rollup.config.js
import { randomUUID } from 'crypto';
import path from 'path';

const styleInjectPath = path
  .resolve('./src/style-inject.js')
  .replace(/[\\/]+/g, '/')

const ids = new Map()
const getUniqueId = (id) => {
  if (ids.has(id)) return ids.get(id)
  const uid = randomUUID()
  ids.set(id, uid)

  return uid
}

...
postcss({
      inject(cssVariableName, id) {
        return `
          import styleInject from '${styleInjectPath}';
          styleInject(${cssVariableName}, 'style-${getUniqueId(id)}');
        `
      },
    }),
...

In the Next js project

// next pages/_document.js
import React from 'react'

type SSRCssModule = {
  css: string
  id: string
}
interface GlobalThis {
  ssrCss?: SSRCssModule[]
}

declare const globalThis: GlobalThis

const SSRInjectStyles: React.FC = () => {
  if (!globalThis.ssrCss) return null

  return (
    <>
      {globalThis.ssrCss.map((module: { css: string; id: string }) => (
        <style
          dangerouslySetInnerHTML={{
            __html: module.css,
          }}
          id={module.id}
          key={module.id}></style>
      ))}
    </>
  )
}


export default Document(props) {
  return (
    ...
  <Head>
  ...
  <SSRInjectStyles />
  </Head>
    ...
  )
}

from rollup-plugin-postcss.

alfredosalzillo avatar alfredosalzillo commented on July 27, 2024 1

@cristiannietodev91 the bundler and the import cache of modules should have prevented the duplication when a component is used multiple time during the SSR, but nice catch :)

from rollup-plugin-postcss.

adarsh-drishya avatar adarsh-drishya commented on July 27, 2024

where is globalThis coming from @alfredosalzillo in the first file it is not defined

from rollup-plugin-postcss.

cristiannietodev91 avatar cristiannietodev91 commented on July 27, 2024

your solution works @alfredosalzillo. I put the SSRInjectStyles component within my own library to allow consumers to import it.

and I found that the styles were inserted multiple times. I had to change a little bit your styleInject script by next one.

export default function styleInject(css, id, { insertAt } = {}) {
	if (!css) return;
	if (typeof document === "undefined") {
		globalThis.ssrCss = globalThis.ssrCss || [];
		const keys = globalThis.ssrCss.reduce((acc, curr)=> {
			return {
				...acc,
				[curr.id]: {
					...curr
				}
			};
		},{});
		if(!keys[id]){
			globalThis.ssrCss.push({ css, id });
		}
		return;
	}

	if (document.getElementById(id)) return;

	const head = document.head || document.getElementsByTagName("head")[0];
	const style = document.createElement("style");
	style.id = id;
	style.type = "text/css";

	if (insertAt === "top") {
		if (head.firstChild) {
			head.insertBefore(style, head.firstChild);
		} else {
			head.appendChild(style);
		}
	} else {
		head.appendChild(style);
	}

	if (style.styleSheet) {
		style.styleSheet.cssText = css;
	} else {
		style.appendChild(document.createTextNode(css));
	}
}

from rollup-plugin-postcss.

alfredosalzillo avatar alfredosalzillo commented on July 27, 2024

@adarsh-drishya wich bundler are you using?

from rollup-plugin-postcss.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.