vercel / next.js

The React Framework
https://nextjs.org
MIT License
124.84k stars 26.65k forks source link

FOUC with styled-jsx on Firebase Cloud Functions #3434

Closed mikemclin closed 6 years ago

mikemclin commented 6 years ago

Expected Behavior

I visit homepage and expect to see styled content immediately.

Current Behavior

Webpage does not immediately render styles in <style jsx> tags. It does however, render styles declared explicitly within a components style attribute. For example, in the code below, the text is blue on page load (immediately), but the .hello styles do not load immediately.

Steps to Reproduce (for bugs)

I am using Firebase Cloud Functions for the server portion of app. The .babelrc file is used both for next build and for a custom deployment step I need to perform to get the source files working on Cloud Functions. Firebase Cloud Functions do not install devDependencies, and it was complaining that both babel-runtime and styled-jsx were not found, so I added them to my dependency list.

// pages/index.js

export default () => (
  <div className='hello'>
    <p style={{ color: 'blue' }}>Hello World</p>
    <style jsx>{`
      .hello {
        font: 15px Helvetica, Arial, sans-serif;
        background: #eee;
        padding: 100px;
        text-align: center;
        transition: 100ms ease-in background;
      }
      .hello:hover {
        background: #ccc;
      }
    `}</style>
  </div>
);
// .babelrc

{
  "presets": [
    ["env", { "targets": { "node": "6.11" } }],
    "next/babel",
    "stage-0"
  ],
  "plugins": [
    "transform-inline-environment-variables",
    ["styled-jsx/babel", { "optimizeForSpeed": true }]
  ]
}

// from package.json

{
  "dependencies": {
    "babel-cli": "^6.26.0",
    "babel-plugin-transform-inline-environment-variables": "^0.2.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-stage-0": "^6.24.1",
    "babel-runtime": "^6.26.0",
    "firebase-admin": "^5.5.1",
    "firebase-functions": "^0.7.3",
    "next": "^4.2.0",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "styled-jsx": "^2.2.1"
  },
}
mikemclin commented 6 years ago

Styles are rendered correctly when I run the app locally using next command.

dmalik commented 6 years ago

Got same issue.

mikemclin commented 6 years ago

I'm still searching for a solution on this. Haven't been able to find one yet. It appears this boilerplate project ananddayalan/nextjs-in-firebase-with-bootstrap is having the same issue. You can see his FOUC on their demo: https://nextjs-in-firebase-functions.firebaseapp.com/ (note that the layout is controlled via style-jsx, the rest of the styles are coming from a CSS file)

JohnWooS commented 6 years ago

Anybody found a solution for this? I also got the same issue.

JohnWooS commented 6 years ago

@mikemclin Did you found a solution for this?

mikemclin commented 6 years ago

@JohnWooS No. I will definitely post back here if I find something. I've tried borrowing config from the Firebase Functions Next.js Example and literally any type of Firebase/Next.js boilerplate I could find on Github. No luck.

I'm sort of just hoping for an official word at this point. I just wish I knew if it was broken, or if I haven't found the magic config sauce yet (even if it is hacky).

jthegedus commented 6 years ago

@mikemclin Have you found any Nextjs/Firebase project where this doesn't occur but where there's no discernable difference in the codebase?

mikemclin commented 6 years ago

@jthegedus No. I have never seen styled-jsx work with SSR on Firebase Cloud Functions.

andyeskridge commented 6 years ago

I have been playing around with this and I think I have fixed it for myself. I created a custom _document.js but it just implements the basic Document functionality.

import Document, { Head, Main, NextScript } from "next/document";
import flush from "styled-jsx/server";

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const { html, head, errorHtml, chunks } = renderPage();
    const styles = flush();
    return { html, head, errorHtml, chunks, styles };
  }

  render() {
    return (
      <html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

I then included styled-jsx as an actual dependency of my app. This combination seemed to fix my first FOUC that I would see on loading.

mikemclin commented 6 years ago

@andyeskridge solution worked for me. I simply added the _document.js file to my pages directory with the content he provided.

I also tried to create a _document.js file that only contained...

module.exports = require('next/document');

...but it failed to render SSR styles.

lacymorrow commented 6 years ago

@mikemclin I just solved this issue as well, the important bit from @andyeskridge's custom _document.js is the flush() after calling renderPage().

timneutkens commented 6 years ago

I'm guessing this might have been solved by Next.js 5 (universal webpack)