Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS styles disappear after refresh in React app

I'm at a loss when it comes to figuring out why this is happening. Right now my hunch is that this is a Webpack issue. I don't have this refresh problem on the dev environment, but only when I build and run that code.

Basically, when I'm on certain pages, and I refresh the app ... all the styles I have in a stylesheet are being ignored, and when I check the response it is actually just showing my index.html page.

Network Response

I am importing the styles into the root of my app, so in the index.js. I know it is still going through that on refresh cause that's where my persistedState logic is happening, and what allows the refresh to work.

Here is my webpack config for production environment. I feel like that has to be the problem somewhat, since the dev environment is just fine. Unless I'm not thinking of other potential problems?

import webpack from 'webpack';
import path from 'path';
import ExtractTextPlugin from 'extract-text-webpack-plugin';

const GLOBALS = {
  'process.env.NODE_ENV': JSON.stringify('production')
};

export default {
  debug: true,
  devtool: 'source-map',
  noInfo: false,
  entry: [
    './src/index'
  ],
  target: 'web',
  output: {
    path: __dirname + '/dist', // Note: Physical files are only output by the production build task `npm run build`.
    publicPath: '/',
    filename: 'bundle.js'
  },
  devServer: {
    contentBase: './dist'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin(GLOBALS),
    new ExtractTextPlugin('styles.css'),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin()
  ],
  module: {
    loaders: [
      {test: /\.js$/, include: path.join(__dirname, 'src'), loaders: ['babel']},
      {test: /(\.css)$/, loader: ExtractTextPlugin.extract("css?sourceMap")},
      {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
      {test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000'},
      {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
      {test: /\.(jpe?g|png|gif|svg)$/i, loader: "file"},
      {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'}
    ]
  }
};

Would love anyones thoughts or solutions to this problem!

EDIT:

Here is the webpack dev config:

import webpack from 'webpack';
import path from 'path';

export default {
  debug: true,
  devtool: 'cheap-module-eval-source-map',
  noInfo: false,
  entry: [
    //'eventsource-polyfill', // necessary for hot reloading with IE
    'babel-polyfill',
    'webpack-hot-middleware/client?reload=true', //note that it reloads the page if hot module reloading fails.
    './src/index'
  ],
  target: 'web',
  output: {
    path: __dirname + '/dist', // Note: Physical files are only output by the production build task `npm run build`.
    publicPath: '/',
    filename: 'bundle.js'
  },
  devServer: {
    contentBase: './src'
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],
  module: {
    loaders: [
      {test: /\.js$/, include: path.join(__dirname, 'src'), loaders: ['babel']},
      {test: /(\.css)$/, loaders: ['style', 'css']},
      {test: /\.(jpe?g|png|gif|svg)$/i, loader: "file"},
      {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
      {test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000'},
      {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
      {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'}
    ]
  }

};

Head tag of HTML:

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1" charset="utf-8">
    <link rel="shortcut icon" href="favicon.ico">
    <link href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700|Roboto:300,400,900" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Work+Sans:300,400,500|Work+Sans:300,400,500" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/6.0.0/normalize.min.css">
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" />
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" />
  </head>
like image 989
Taylor King Avatar asked May 03 '17 14:05

Taylor King


People also ask

Why is my CSS not being applied React?

This error is generated because the compiler is only able to import files from the src folder. Here, the CSS file is saved outside the src folder, so the compiler failed to import it. To make this code work, you just have to save the CSS file inside the src folder.

How do you maintain state after page refresh in React?

To maintain state after a page refresh in React, we can save the state in session storage. const Comp = () => { const [count, setCount] = useState(1); useEffect(() => { setCount(JSON. parse(window. sessionStorage.

Does React take care of CSS?

React doesn't do styling React components output HTML, and CSS styles the HTML. As far as the browser is concerned, React doesn't figure into it. The browser applies CSS rules to the HTML on the page, whether that HTML came from an . html file or was generated by React.


1 Answers

You are using a relative path to the CSS file in your HTML:

<link rel="stylesheet" href="styles.css">

When you visit /example/page/ you're trying to request /example/page/styles.css, but as that doesn't exist, your server falls back to index.html. You're using that behaviour because you always want to serve the same page and your JavaScript will decide what it should render.

Similarly to how you always request /bundle.js, you also want to request /styles.css regardless of the actual URL.

<link rel="stylesheet" href="/styles.css">

This issue only appears in your production build, because you are using style-loader in development, which injects the CSS into a <style> tag from your JavaScript.

like image 168
Michael Jungo Avatar answered Oct 10 '22 04:10

Michael Jungo