Reputation: 5683
Just started out using React yesterday so setting up a demo app. Environment is:
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>
);
}
}
Upvotes: 49
Views: 133723
Reputation: 41
You have to Import Bootstrap library in your code
import 'bootstrap/dist/css/bootstrap.css';
Import this library into your app.js
This works in my case
Upvotes: 3
Reputation: 105
Are you on node v16.15.0 and above?
Do either of the following:
yarn add react-bootstrap bootstrap
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.
Upvotes: 8
Reputation: 388
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.
Upvotes: 0
Reputation: 859
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.
Upvotes: 12
Reputation: 157
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>
Upvotes: 1
Reputation: 71
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
Upvotes: 7
Reputation: 91
At App.css
just paste the following import:
@import "bootstrap/dist/css/bootstrap.css";
Upvotes: 9
Reputation: 764
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!
Upvotes: 58
Reputation: 961
I ran into the same issue and this worked for me -->
I ended up installing bootstrap with npm:
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:
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.
Upvotes: 96
Reputation: 3473
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.
Upvotes: 9