43

Just started out using React yesterday so setting up a demo app. Environment is:

  1. Typescript
  2. Webpack
  3. React & React DOM

I'm trying to setup Bootstrap styles.

I followed this tutorial along but modified it to suit Typescript:

https://medium.com/@victorleungtw/how-to-use-webpack-with-react-and-bootstrap-b94d33765970

Everything works, the page displays the signin form and the Bootstrap HTMl is output by React-Bootstrap. But the styles are not applied to the elements, it's just a plain HTML page with none of the Bootstrap styles applied. I'm not sure what I'm missing from the config:

webpack.config.js

I've added the loaders through npm as mentioned in the tutorial, but also adjusted to setup Typescript modules from the css.

module.exports = {
    entry: {
        catalog: "./src/apps/CatalogApp.tsx",
        auth: "./src/apps/AuthApp.tsx"
    },
    output: {
        filename: "[name].bundle.js",
        publicPath: "/build/",
        path: __dirname + "/dist"
    },

    // Enable sourcemaps for debugging webpack's output.
    devtool: "source-map",

    resolve: {
        // Add '.ts' and '.tsx' as resolvable extensions.
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
            // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
            {
                test: /\.tsx?$/,
                loader: "awesome-typescript-loader"
            },

            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            {
                enforce: "pre",
                test: /\.js$/,
                loader: "source-map-loader"
            },

            // css loader
            {
                test: /\.css$/,
                loader: "typings-for-css-modules-loader?modules"
            },

            {
                test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, 
                loader: 'url-loader?limit=10000&mimetype=application/font-woff'
              },
              {
                test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, 
                loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
              },
              {
                test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, 
                loader: 'file-loader'
              },
              {
                test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, 
                loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
              }
        ]
    },

    // When importing a module whose path matches one of the following, just
    // assume a corresponding global variable exists and use that instead.
    // This is important because it allows us to avoid bundling all of our
    // dependencies, which allows browsers to cache those libraries between builds.
    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    }
};

AuthApp.tsx

This is my entry point for the application.

import * as React from "react";
import * as ReactDOM from "react-dom";

import { SigninForm } from "../components/users/SigninForm";
import { MiniCart } from '../components/cart/MiniCart';
import { UserMenu } from '../components/users/UserMenu';
import * as bs from 'bootstrap/dist/css/bootstrap.css';
import * as bst from 'bootstrap/dist/css/bootstrap-theme.css';

if (document.getElementById("signin-form")) {
    ReactDOM.render(
        <SigninForm />,
        document.getElementById("signin-form")
    );
}

if (document.getElementById('cart')) {
    ReactDOM.render(
        <MiniCart />,
        document.getElementById('cart')
    );
}

if (document.getElementById('user-menu')) {
    ReactDOM.render(
        <UserMenu />,
        document.getElementById('user-menu')
    );
}

SigninForm.tsx

And the relevant UI for the signin form.

import * as React from 'react';
import * as ReactDOM from "react-dom";
import { Button, Col, Row } from 'react-bootstrap';

import { Spinner } from '../shared/Spinner';

interface SigninFormProps {
}

interface SigninFormState {
  email: string;
  password: string;
}

export class SigninForm extends React.Component<SigninFormProps, SigninFormState> {

  constructor(props: SigninFormProps) {
    super(props);
    this.state = {
      email: '',
      password: ''
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event: any) {
    this.setState({ [event.target.name]: event.target.value });
  }

  handleSubmit(event: any) {
    event.preventDefault();
    console.log('Submitting form', this.state);
  }

  render() {
    return (
      <Row>
        <Col md={8}>
          <form className="signin-form" onSubmit={this.handleSubmit}>
            <div className="form-group">
              <label htmlFor="email">Email</label>
              <input id="email" name="email" type="email" value={this.state.email} onChange={this.handleChange} />
            </div>
            <div className="form-group">
              <label htmlFor="password">Password</label>
              <input id="password" name="password" type="password" value={this.state.password} onChange={this.handleChange} />
            </div>
            <Button>Submit</Button>
          </form>
        </Col>
        <Col md={4}>
          Right Side
      </Col>
      </Row>
    );
  }
}
Richard G
  • 5,243
  • 11
  • 53
  • 95

10 Answers10

84

I ran into the same issue and this worked for me -->

I ended up installing bootstrap with npm:

  • 1) npm i --save bootstrap

Then, in index.js (where I render App.js) I imported bootstrap's minified css file from nodes_modules like so:

  • 2) import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

Now the responsive positioning is working (where as before I saw react-bootstrap rendering the correct class names, but without styling).

Note: https://react-bootstrap.github.io/getting-started/introduction says you should add the css to the head of index.html. I did not have success doing it this way.

Jamie Ronin
  • 841
  • 6
  • 4
  • 1
    I also have not had success with adding the script tags to the index.html...but its probably because there are some things I'm not understanding. This worked for me! – Mike Kellogg Apr 24 '19 at 15:32
  • for me it was just 'bootstrap/dist/css/bootstrap.min.css' you dont need to explicitly import from 'node_modules' irrespective of the part underneath 'src' you may be. – khanna Apr 18 '20 at 12:36
  • you saved the year bro!! – Charleskimani Jan 27 '21 at 09:49
50

First of what you need to is to Install Bootstrap using NPM

npm install --save bootstrap

then

go for writing this statement in which component you have to use bootstrap, This works in my case.

import 'bootstrap/dist/css/bootstrap.css';

CSS Styling will start working. :)

Happy Coding!

Syed Umer Hasan
  • 644
  • 7
  • 11
  • 1
    This idea solved my issue. https://getbootstrap.com/docs/4.4/getting-started/webpack/#importing-compiled-css – Aswin Prasad Apr 11 '20 at 22:25
  • 3
    import 'bootstrap/dist/css/bootstrap.css'; Works for me.. – Amit Dwivedi Mar 10 '21 at 18:26
  • This seems like the right answer. It could be improved by explaining why... I suspect the reason is that react-bootstrap just wraps the css as component objects, but css still required. Maybe this provides for the ability to upgrade and theme bootstrap... or it provides the nightmare of compatible versions of bootstrap vs. react-bootstrap, lol, who knows, we will see! – gunslingor Jul 31 '22 at 20:08
  • I would like to clarify, why bootstrap is not included automatically, when we download, any specific npm package. js build files are inside `node_modules`, they are not imported/referenced in your frontend code, so in order to include `bootstrap`, we have to use `import 'bootstrap/dist/css/bootstrap.css';` to include bootstrap css. – Syed Umer Hasan Nov 07 '22 at 09:14
10

Not sure if it is relevant at this time I checked your post. However, I am able to use react-bootstrap. According to react-bootstrap, you will have to add

<link
    rel="stylesheet"
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
    integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
    crossorigin="anonymous"
/>

which I added in into my index.html header tag.

And I have also added import "react-bootstrap/dist/react-bootstrap.min.js"; in my app.js.

cakan
  • 2,099
  • 5
  • 32
  • 42
csamleong
  • 769
  • 1
  • 11
  • 24
9

The webpack config you use is a little different from the medium article.

In the medium article, the author uses style-loader and css-loader to process css file.

module.exports = {
  entry: './main.js',
  output: { path: __dirname, filename: 'bundle.js' },
  module: {
    loaders: [
      ...
      { 
        test: /\.css$/, 
        loader: "style-loader!css-loader" 
      },
      ...
    ]
  },
};

style-loader will inject the css code to <style/> tag. So that is why the tutorial work

In your webpack config, you use typings-for-css-modules-loader to load css. With this loader, you need to pass the css class variable name to className.

It means you should write the code like (simplify some code):

import * as React from "react";
import * as bs from 'bootstrap/dist/css/bootstrap.css';
import * as bst from 'bootstrap/dist/css/bootstrap-theme.css';

import { Button, Col, Row } from 'react-bootstrap';

import { Spinner } from '../shared/Spinner';

export class SigninForm extends React.Component {
  ...
  render() {
    return (
      <Row>
        <Col md={8}>
          <form className={bt["signin-form"]} onSubmit={this.handleSubmit}>
            <div className={bt["form-group"]}>
              <label htmlFor="email">Email</label>
              <input id="email" name="email" type="email" value={this.state.email} onChange={this.handleChange} />
            </div>
            <Button>Submit</Button>
          </form>
        </Col>
        <Col md={4}>
          Right Side
      </Col>
      </Row>
    );
  }
}

Pass bt[classname] to className.

I think it will work.

btw, I find another medium article using typings-for-css-modules-loader -> link.

Chen-Tai
  • 3,435
  • 3
  • 21
  • 34
  • thx will try this when I get home today. but it wouldnt fix the layout components right? the row and col tags are not working either. – Richard G Nov 18 '17 at 03:22
  • also the article is the one I referenced to choose typings css loader. it seems to conclude that just importing the stylessheet should work unless I read it wrong... – Richard G Nov 18 '17 at 03:24
  • 1
    @RichardG The [react-bootstrap doc](https://react-bootstrap.github.io/getting-started.html) said: `Because React-Bootstrap doesn't depend on a very precise version of Bootstrap, we don't ship with any included css`. So you need to include bootstrap css by yourself. – Chen-Tai Nov 18 '17 at 03:26
  • actually they're also using style loader and named exports option. maybe using style loader will fix it. – Richard G Nov 18 '17 at 03:30
  • Yeah, that's right. The medium article you post is import bootstrap in js file and use `css-loader | style-loader` to load it. That is one method to do the trick. – Chen-Tai Nov 18 '17 at 03:32
  • ok i ended up using style loader but had to switch off modules mode. Then it started working. This is fine I wanted global bootstrap classes anyway. I then imported the files at the entry point of the app rather than in the component. Also adjusted the form controls to use the react-bootstrap components rather than building my own. – Richard G Nov 18 '17 at 13:46
8

At App.css just paste the following import:

@import "bootstrap/dist/css/bootstrap.css";
DuDa
  • 3,718
  • 4
  • 16
  • 36
DarKayserLeo
  • 81
  • 1
  • 1
6

Please try to add this line in index.js

import 'bootstrap/dist/css/bootstrap.min.css';

Adding this to App.js file doesn't work for me

Anoop
  • 61
  • 1
  • 3
4

Are you on node v16.15.0 and above?

Do either of the following:

  1. Using yarn? run- yarn add react-bootstrap bootstrap
  2. Using npm? run- npm install react-bootstrap bootstrap

Then add this line in your App.js - import 'bootstrap/dist/css/bootstrap.css';

Then restart your react app. It should work after that.

1

Along with bootstrap.min.js, we need to use bootstrap.min.css in order to have bootstrap working. Visit https://www.bootstrapcdn.com/ and copy links under CSS and JavaScript and paste it in the HTML file under head tag.

Use as below and change the bootstrap version accordingly.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap**@5.1.1**/dist/css/bootstrap.min.css"  crossorigin="anonymous"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap**@5.1.0**/dist/js/bootstrap.min.js" crossorigin="anonymous"></script>
Vidya Sagar H J
  • 157
  • 1
  • 3
1

You have to Import Bootstrap library in your code

import 'bootstrap/dist/css/bootstrap.css';

import this library in your app.js

This work in my case

0

There's also the official solution from React-Bootstrap:

1 - Import the component to use:

import Button from 'react-bootstrap/Button';

or less ideally import { Button } from 'react-bootstrap';

2 - Import the required stylesheets for the components' styles to be applied properly:

import 'bootstrap/dist/css/bootstrap.min.css';

Refresh your page, now the default styling from bootstrap should be applied properly.

Sunamin34
  • 174
  • 1
  • 7