Exploring the integration of Styled-components in NextJs13 for server-side rendering

ERROR MESSAGE:

The server encountered an error. The specific error message is: TypeError: createContext only works in Client Components. To resolve this issue, add the "use client" directive at the top of the file. More information can be found here



import Link from "next/link";
import StyledHero from "./Hero.style";

const Hero = () => {
    return (
        <StyledHero>
            <h1>Stowarzyszenie Juz Lepiej</h1>
            <h2>Przybywam w celu:</h2>
            <Link about="Panel wolontariusza" href={"/volunteer"}>Uzyskania pomocy</Link>
            <Link about="Panel podopiecznego" href={"/mentee"}>Niesienia pomocy</Link>
            
        </StyledHero>
    )
};

export default Hero;


import styled from "styled-components";

const StyledHero = styled.main`
    width: 100%;
    height: auto;
    padding: 10em;

`
export default StyledHero;

I am encountering an error when using Styled Component. How do I use StyledComponents with SSR in Next13? None of the solutions I have found are working. However, changing <StyledHero> to <main></main> fixes the issue.

I have tried configuring .babelrc as follows:

{
    "presets": [
      "next/babel"
    ],
    "plugins": [
     [
       "styled-components",
       {
          "ssr": true,
          "displayName": true,
          "preprocess": false
        }
     ]
    ]
}

This is my package.json configuration:

{
  "name": "mentalhealthcharity",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@next/font": "13.2.4",
    "@types/node": "18.15.11",
    "@types/react": "18.0.31",
    "@types/react-dom": "18.0.11",
    "@types/styled-components": "^5.1.26",
    "eslint": "8.37.0",
    "eslint-config-next": "13.2.4",
    "next": "13.2.4",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "styled-components": "^5.3.9",
    "typescript": "5.0.2",
    "zustand": "^4.3.6"
  },
  "devDependencies": {
    "babel-plugin-styled-components": "^2.0.7"
  }
}

Answer №1

After thoroughly investigating this matter, it appears that implementing styled-components for server-side rendering in Next.js 13 with the app router is not feasible. However, there are workarounds to ensure styled-components function properly in Next.js 13 without encountering any "delay bugs" by utilizing client-side rendering.

To achieve this, follow these steps:

  1. Include the code snippet below in your next.config.js file:

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  compiler: {
    styledComponents: true,
  },
}

module.exports = nextConfig

  1. Create a registry.tsx file containing the provided code:

'use client'
 
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
 
export default function StyledComponentsRegistry({
  children,
}: {
  children: React.ReactNode
}) {
  // Only create stylesheet once with lazy initial state
  // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
  const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
 
  useServerInsertedHTML(() => {
    const styles = styledComponentsStyleSheet.getStyleElement()
    styledComponentsStyleSheet.instance.clearTag()
    return styles
  })
 
  if (typeof window !== 'undefined') return <>{children}</>
 
  return (
    <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
      {children}
    </StyleSheetManager>
  )
}

3 - Insert the 'use client' directive into your layout.tsx file and wrap all the child components of your layout with the StyledComponentsRegistry component.

I have created a detailed tutorial video on Youtube addressing this issue, which elaborates on the workaround:

watch?v=3tgrPm2aKog

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Determining the most appropriate time to utilize the 'async' built-in function in ES2017 versus implementing 'npm i async' can depend on a variety of factors such

I recently discovered that async/await is a feature of ES2017, however, in some of my previous projects I had to use the package async to implement async/await functionality. Is there a simple way to determine when async can be used without importing it? ...

Combining multiple arrays of arrays in JavaScript

I am dealing with an array that contains nested arrays. This particular array is called template template consists of 2 arrays, but the number can vary and there can be multiple levels of arrays within each one. Here's what I have attempted: const ...

Adding JSON information into a .js file using ajax technology

I am currently working on integrating a calendar template into my system. In the demo JavaScript file, example events are structured like this: events: [ { id: 1, title: 'Title 1', start: ('2016-01-02'), ...

Throw TypeError: The `pipe` property of `ngrx/store` is undefined during testing

Here is the code snippet from my TypeScript file: this.store.pipe(select(subscribe.getRegCategories)).pipe(takeUntil(this.ngUnsubscribe)).subscribe(data => { if (data && data.length) { this.allRegCategories = data; ...

Organizing Telephone Number Entries in Angular

In my search for a way to format a phone number input field in Angularjs, I have come across many solutions, but none specifically for Angular 7. What I am looking to achieve is for the user to enter the textfield like so: 123456789 and have the textfi ...

Initiate the function one time

The Introduction: I need assistance with a form that triggers a jQuery function when a button is clicked. The issue arises after the initial execution, as the function continues to run one more time. My dilemma is figuring out how to ensure that the funct ...

Guide to Automatically Updating Angular Component When Service Data Changes

I am currently working on an Angular application that features a sidebar component displaying different menu items based on the user's data. The sidebar should only display an option for "Empresas" if the user has not created any company yet. Once a c ...

Combining Python Bottle with Polymer Paper Elements

My website currently has a variety of forms where users input information, which is then used to calculate and display new content using Javascript. I rely on Python Bottle for user registration, form auto-filling from the backend and database management. ...

Gain access to the "computed style" of elements in a directive

I recently created a directive for a loader element, but I am facing issues with undefined styles. Is there a way to access the "computed styles" of an element within the directive? export const ElementLoader = { componentUpdated(el, binding) { if ...

I have a question for you: How can I customize the font size in Material-UI TextField for different screen sizes?

I'm facing a challenge in Material-UI where I need to set different font sizes for TextField. While it may be simple in HTML/CSS, it's proving to be tricky in Material-UI. Can anyone help me figure out how to achieve this? The code snippet below ...

Shadows on menu buttons transform when clicked using React and CSS

I'm currently working on customizing the styling of a menu using CSS in a project that involves the use of "react-horizontal-scrolling-menu". While I've been successful in styling the menu items with .menu-item:hover & .menu-item:active, I am ...

When attempting to access index.html, the Express Server responds with a "Page Not Found"

I have encountered a problem while trying to run my Index.html file through an Express server. Despite referring to previously asked questions, I couldn't resolve the issue. The error message 'Cannot GET /' keeps popping up. Below is the sn ...

Is there a JavaScript function available that can be used to execute a script once content has been loaded via AJAX?

There are multiple inquiries regarding executing a JavaScript function after content is loaded via Ajax. I am familiar with the common solution of running JS after Ajax load completion. If more than 40 pages are loading a page my-Page.php using Ajax, is t ...

Issue with displaying nested React Elements from Component

I am currently facing an issue with my Collection component, which is utilizing a sub-component called RenderCollectionPieces to display UI elements. Strangely, I am able to see the data for image.name in the console but for some reason, the UI elements ar ...

Encountering an issue with Spring and AngularJS, as I am receiving an HTTP Status 404 error message

I'm encountering an HTTP Status 404 error within my controller. Server code @RequestMapping(value="/showMsg/", method=RequestMethod.GET,produces= { "application/json" })' public ResponseBody String show(){ HashMap hash = new HashMap(); ...

The ExpressJS app generator seems to be struggling to identify and interpret the flags

I seem to be having trouble running the express app generator with flags. For example, when I run express --version, it interprets the --version part as a target directory and creates the app there. This is happening on Windows XP SP3. Could I be doi ...

Adjusting the size of content tags depending on their popularity

Currently, I am working on setting up a basic tagging system by following the database structure provided in this Stack Overflow post. My goal is to create a single page that showcases all the tags, with each tag being visually scaled based on its popular ...

Can we selectively execute certain tests in Cypress using support/index.js?

I need to selectively run certain tests from a pool of 50 test files located in the integration folder. Specifically, I only want 10 of them to execute. In an attempt to achieve this, I am trying to configure the selection process within the support/index. ...

Screen goes dark after switching to full-screen mode (panolens.js/three.js)

Utilizing a library known as panolens for displaying a 360-degree panoramic view, hinging on three.js. Within my application, there are two views: one containing custom content and the other serving as a container for panolens. Initially, the first view is ...

Tips for utilizing maps in a react component within a Next.js application

I received an array of data from the backend that I need to display on a React component. home.js import Head from "next/head"; import Header from "../src/components/Header"; import * as React from 'react'; import { styled } ...