How to apply styles to the react component via css modules - javascript

Ive got a problem with applying styles to my React Components.
I generated template to my project via Yeoman. It created a lot of config files, not only webpack.config.js and because of that I'm a little bit confused. As Readme file of react-generator says it support out of the box some features without installing it:
*Different supported style languages (sass, scss, less, stylus)
*Style transformations via PostCSS
According to this I show part of cfg/default.js
'use strict';
const path = require('path');
const srcPath = path.join(__dirname, '/../src');
const dfltPort = 8000;
function getDefaultModules() {
return {
preLoaders: [{
test: /\.(js|jsx)$/,
include: srcPath,
loader: 'eslint-loader'
}],
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader!postcss-loader'
},
{
test: /\.sass/,
loader: 'style-loader!css-loader!postcss-loader!sass-loader?outputStyle=expanded&indentedSyntax'
},
{
test: /\.scss/,
loader: 'style-loader!css-loader!postcss-loader!sass-loader?outputStyle=expanded'
},
{
test: /\.less/,
loader: 'style-loader!css-loader!postcss-loader!less-loader'
},
{
test: /\.styl/,
loader: 'style-loader!css-loader!postcss-loader!stylus-loader'
},
I think this part is responsible for converting .scss files.
So in my todosStyle.scss file I've got this code:
.todos {
display: flex;
flex-flow: row wrap;
justify-content: center;
width: 100%;}
.input {
display: block;
text-align: center;}
.button {
width: 60px;
margin: 5px; }
.label {
display: block;
border: solid 1px; }
Base on this styling I want to style my component Todos.jsx:
import React from "react";
import Todo from "./Layout/Todo.jsx";
import TodoStore from "../../stores/TodoStore.jsx";
import * as TodoActions from "../../actions/TodoActions.jsx";
import styles from '../../styles/todosStyle.scss';
export default class Todos extends React.Component {
constructor() {
super();
this.getAllTodos = this.getAllTodos.bind(this);
this.state = {
todos: TodoStore.getAll(),
};
}
getAllTodos(){
this.setState({
todos: TodoStore.getAll(),
});
}
componentWillMount(){
TodoStore.on('change', this.getAllTodos);
}
componentWillUnmount(){
TodoStore.removeListener('change', this.getAllTodos);
}
createTodo(){
if (this.refs.addTodo.value != ''){
TodoActions.createTodo(this.refs.addTodo.value);
this.refs.addTodo.value = '';
}
}
deleteTodo(todo){
TodoActions.deleteTodo(todo);
}
completeTodo(todo){
TodoActions.completeTodo(todo);
}
render() {
const {todos} = this.state;
const TodoComponents = todos.map(todo =>{
return <Todo key={todo.id} {...todo} completeTodo={this.completeTodo.bind(this, todo)} deleteTodo={this.deleteTodo.bind(this, todo)}/>;
});
return (
<div>
<h1>Todos</h1>
<div class = {styles.input}>
<label class= {styles.label}>Add new Todo</label>
<input ref="addTodo"/>
<button class={styles.button} onClick = {this.createTodo.bind(this)}><i class="fa fa-plus-square-o"></i></button>
</div>
<ul class={styles.todos} class="row">{TodoComponents}</ul>
</div>
);
}
}
but styling isn't applied, although I've imported todosStyle.scss
Could someone help me?

Just a note, its good to add $ on your loader test properties eg. test: /.scss$/, to only match end of file i believe.
i havent seen this before "import styles from '../../styles/todosStyle.scss';"
this kind of says that you are exporting styles from your sass file, perhaps import * as style ... might work, but i haven't used this approach.
try this.
require ('../../styles/todosStyle.scss');
this will bundle your css with the javascript.
then just use the class as you normally would on your render function.
also note; if you would like to create a separate file for your css, you can do that with plugins.

You're using css modules but you haven't turned them on in your Webpack config:
loader: 'style-loader!css-loader!postcss-loader'
becomes
loader: 'style-loader!css-loader?modules!postcss-loader'
As per the css-loader readme https://github.com/webpack/css-loader#css-modules.

Related

loading css in asynchronously imported javascript using webpack with MiniCssExtractPlugin

i'm working on a webapp that loads it's different pages asynchronously via dynamic imports e.g.:
import {Component, h} from "preact";
import AsyncRoute from "preact-async-route";
import {Layout} from "components/layout";
import {PageLoading} from "components/page-loading";
export class Page extends Component {
render() {
return (
<Layout>
<AsyncRoute
key="doorstation"
path={"/doorstation"}
getComponent={this.getSamplePage}
loading={() => <PageLoading />}
/>
</Layout>
);
}
async getSamplePage(){
const { init, Page } = await import("modules/sample");
init();
return Page;
}
}
and in the actual imported file i do
// modules/sample/page/index.tsx
import {Component, h} from "preact";
import styles from "./styles.css";
export class Page extends Component {... components logic}
// modules/sample/index.tsx
export const init = () => // some initialization logic
export { Page } from "./Page"
Each of those pages has their own css that gets imported on their respective file. What i'm stuck now with is that it puts the resulting css in it's own chunk but when the browser build tries to import said css it just fails with an error like:
GET http://<my-ip>/341.()=%3E%225028a51a47a787d4cc85%22.css net::ERR_ABORTED 404 (Not Found)
Error: Loading CSS chunk 341 failed.
(/341.()=>"5028a51a47a787d4cc85".css)
at o.<computed>.o.<computed>.<computed>.e.push.o.<computed>.d.onerror
on inspection of the import on the console the href of resulting stylesheet tag is actually set to:
link.href = "http://<my-ip>/341.()=%3E%225028a51a47a787d4cc85%22.css"
what i expected was that webpack would resolve those paths on my dynamically imported modules but apparently this isn't the case.
for now my config looks like this:
module: {
rules: [
test: /\.css$/,
use: [
{
loader: args.mode === "production" ? MiniCssExtractPlugin.loader : "style-loader",
},
{
loader: "css-loader",
options: {
sourceMap: args.mode !== "production",
importLoaders: 1,
modules: {
localIdentName:
args.mode === "production"
? "c-[hash:base64:8]"
: "[name]-[local]-[hash:base64:4]",
},
},
},
{
loader: "postcss-loader",
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[hash:8].css",
chunkFilename: "[name].[hash:8].css",
}),
]
by just using the style-loader everything works just fine but this won't give me actual css chunks. I'm not entirely sure where or what to change so webpack will require the actual css chunk files instead of resolving the path with that... what looks like an function expression. I was already looking up the issue but so far it didn't really solve my issue since it usually revolved around undefined values or something.
Did i miss something in this config? is someone able to help?
Thank you in advance.

How can I wrap a material-ui react component to a Web Component without losing the styles?

I'm developing a wrapper to transpile React components into Web Components. What do I need to apply the styles when the components are rendered in the shadow DOM?.
I am trying to wrap a material-ui react component (Button) in a Web Component, however when I attach the component to the shadow DOM the styles are not applied.
//Wrapper
import ReactDOM,{ render } from 'react-dom';
import Button from '#material-ui/core/Button';
class ButtonWrapper extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
const mountPoint = document.createElement('span');
this.attachShadow({ mode: 'open' }).appendChild(mountPoint);
ReactDOM.render(
<Button variant="contained" color="primary">
Material Button
</Button>
, mountPoint);
}
}
customElements.define('button-material-wrapper', ButtonWrapper);
//HTML
<button-material-wrapper></button-material-wrapper>
//Webpack.config
...
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: { presets: ['#babel/preset-env', '#babel/preset-react'] }
}
},
{
test:/\.(s*)css$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
}
....
Expected output:
The material-ui button is correctly rendered
Actual output:
The material-ui button is corectly rendered as a child node of the shadow-root but the material styles are not applied.
In webpack, style-loader helps you to add the style to global document style. But web component can not access the style(including the global material style) outside shadow DOM which result in your Actual output.
One solution I found is to use css-to-string-loader to import the string of the scss of material component manually, and then add it to the style of current shadow DOM by hand.
// Webpack.config
{
test: /.*\.scss$/,
use: ['css-to-string-loader', 'css-loader', 'sass-loader'],
},
// In Web Component (connectedCallback)
const style = document.createElement('style');
const style.innerHTML = require('#material/xxxx.scss');
const head = document.createElement('head');
head.appendChild(style);
this.attachShadow({ mode: 'open' }).appnedChild(head)
In my opinion, it's not elegant at all, looking forward to a better solution.

Can't access global SCSS variables in Storybook with Webpack + React

Trying to get access to global SCSS variables like I have in the rest of my app. I've taken it so far but I'm currently getting this error with the .storybook.scss test file;
The .storybook directory and the src directory are siblings.
-/.storybook
|-config.ts
|-storybook.scss
|-webpack.config.js
-/src
|-/components/
|-/scss/
|-global.scss
ERROR in ./src/components/Global/Dialog/dialog.scss (./node_modules/react-scripts/node_modules/css-loader??ref--8-1!./node_modules/postcss-loader/src??postcss!./node_modules/sass-loader/lib/loader.js??ref--8-3!./node_modules/style-loader!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./src/components/Global/Dialog/dialog.scss)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):
.modal {
^
Invalid CSS after "": expected 1 selector or at-rule, was "var content = requi"
in /Users/hghazni/Sites/eat/src/components/Global/Dialog/dialog.scss (line 1, column 1)
I've attempted to use many different webpack.config.js and config.ts configurations and followed the official documentation on the Storybook website but had no luck.
webpack.config.js
const { resolve } = require('path');
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../src/scss')
},
{
test: /\.css$/,
loader: 'style-loader!css-loader',
include: __dirname
}
]
}
}
config.ts
import { configure } from "#storybook/react";
require('./storybook.scss');
const req = require.context('../src/', true, /.stories.tsx$/);
function loadStories() {
req.keys().forEach((filename) => req(filename))
}
configure(loadStories, module);
.storybook.scss
body {
background: $color-primary;
}
Dialog.tsx
import React from 'react'
import './dialog.scss';
type DialogType = {
onClose: any;
isOpen: any;
}
const Dialog: React.SFC<any> = props => {
let dialog: any = (
<div className={"dialog " + props.dialogClass}>
<button className={"dialogClose"} onClick={props.onClose}>X</button>
<div>{props.children}</div>
</div>
);
if (!props.isOpen) {
dialog = null;
}
return (
<div className="modal">
{dialog}
</div>
)
}
export default Dialog;
dialog.scss
.modal {
position: absolute;
top: 20%;
left: 50%;
-webkit-transform: translate(-50%);
transform: translate(-50%);
width: 95%;
#include media-query(min, $desk-start) {
width: 70%;
max-width: $desk-start;
}
}
.dialog {
border: 4px dashed rgba(47, 144, 189, 0.411);
border-radius: $half-spacing;
padding: $base-spacing;
background: $color-base;
}
.dialogClose {
position: absolute;
top: 0;
right: 0;
padding: $half-spacing;
background: $color-base;
border: 1px solid rgba(47, 144, 189, 0.411);
color: rgba(47, 144, 189, 1);
border-radius: 50px;
padding: $half-spacing 12.5px;
&:hover {
cursor: pointer;
}
}
I'm looking for any support/guidance on how to get storybook to be able to load my SCSS variables located in ../src/scss/global.scss.
So what Storybook or the documentation doesn't explicitly tell you is that having two webpack configs isn't ideal. You'll need to basically cater for a lot of the things needed in your main webpack config if you're trying to mirror your components.
Though there is a way to have to one webpack config with all the options separated so you can reuse it across the site as many times as you need. I even wrote an article about how to do it and built a boiler plate template for you with it already setup if you want to check it out.
https://levelup.gitconnected.com/a-killer-storybook-webpack-config-a0fd05dc70a4
Had same kind of issue, then found that Storybook supports scss configuration out of the box, I removed all rules related to sass/scss from storybook webpack config override and everything worked. However npm i node-sass was needed

Why is my CSS not applying to my React components?

Say I'm creating a React app and have some CSS for components. I've added the style-loader and css-loader to my webpack config here:
module.exports = {
mode: 'development',
entry: './client/index.js',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-react']
}
}
}, {
test: /\.css$/,
loader: 'style-loader'
}, {
test: /\.css$/,
loader: 'css-loader',
query: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
output: {
path: __dirname + '/dist',
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: './dist'
},
devtool:"#eval-source-map"
};
I have a simple CSS file just to test on one component:
.list-group-item {
border: 1px solid black;
outline-style: solid;
outline-color: red;
outline-width: medium;
}
In my app I'm applying the classname to a element in my component and importing my CSS
import React, { Component } from 'react'
import { connect } from 'react-redux'
import selectContact from '../actions/action_select_contact'
import { bindActionCreators } from 'redux'
import '../styles.css';
class ContactList extends Component {
renderList() {
return this.props.contacts.map((contact) => {
return (
<li
key={contact.phone}
onClick={() => this.props.selectContact(contact)}
className='list-group-item'>{contact.firstName} {contact.lastName}</li>
);
});
}
render() {
return (
<ul className = 'list-group col-sm-4'>
{this.renderList()}
</ul>
);
}
}
function mapStateToProps(state) {
return {
contacts: state.contacts
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ selectContact: selectContact }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(ContactList)
I'm also importing the CSS file in the same way in the ContactList component itself. The rest of the project is here. I would have expected to see an outline around my comtactsList but there is not. There is no CSS when I inspect the page. Why is this not getting applied?
In a react project created with create-react-app or npx create-react-app, I also had the same issue.
I had imported index.css file in my App Component but my styles were not being applied properly to my React Components.
I even tried directly adding index.css file in my html file in the public folder and using link tag to link to my index.css file (which resides within src folder).
<link rel="stylesheet" href="./../src/index.css">
That also didn't work.
Finally, I read an article about 7 ways to apply CSS into React. One best way was to install node-sass into our project and use index.scss ( import './index.scss') into App Component instead of index.css.
And Hurray!!! My CSS worked fine, All the Media Queries started to work fine.
Below is the code snippet you can try.
import React from "react";
import ReactDom from "react-dom";
import './index.scss';
// --- Data to work with ---
const books = [
{
id: 1,
name: 'The Rudest Book Ever',
author: 'Shwetabh Gangwar',
img: 'https://m.media-amazon.com/images/I/81Rift0ymZL._AC_UY218_.jpg'
},
{
id: 2,
name: 'The Rudest Book Ever',
author: 'Shwetabh Gangwar',
img: 'https://m.media-amazon.com/images/I/81Rift0ymZL._AC_UY218_.jpg'
},
{
id: 3,
name: 'The Rudest Book Ever',
author: 'Shwetabh Gangwar',
img: 'https://m.media-amazon.com/images/I/81Rift0ymZL._AC_UY218_.jpg'
},
{
id: 4,
name: 'The Rudest Book Ever',
author: 'Shwetabh Gangwar',
img: 'https://m.media-amazon.com/images/I/81Rift0ymZL._AC_UY218_.jpg'
},
];
const Book = ({ book }) => {
return (
<div className={"book"}>
<img src={book.img} alt="book image" />
<h3>{book.name}</h3>
<p>{book.author}</p>
</div>
)
};
const Books = () => {
return (
<main className={"books"}>
{
books.map(book => {
return (<Book book={book} key={book.id} />)
})
}
</main>
)
};
// Work a bit fast | one step at a time
const App = () => {
return (
<main>
<h2>Books</h2>
<Books />
</main>
)
}
ReactDom.render(<App />, document.getElementById("root"));
/* --- Mobile First Design --- */
.books{
text-align: center;
};
.book{
border: 1px solid #ccc;
text-align: center;
width: 200px;
padding: 1rem;
background: #001a6e;
color: #fff;
margin:auto;
};
h2{
text-align: center;
}
/* --- Adding Media Queries --- */
#media only screen and (min-width: 900px){
.books,.persons{
display:grid;
grid-template-columns: 1fr 1fr;
}
}
To install node-sass, simple do npm install node-sass --save
Then rename all your .css files with .scss and your project with work properly.
The package.json should have the node-sass dependency added as shown below:
"dependencies": {
"node-sass": "^4.14.1",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-scripts": "2.1.5"
},
Hope this will help many developers :)
It would be helpful to see your React component as well.
Given this code, you are passing className as a property into the component rather than assigning a class to it:
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
render() {
return (
<div>
/** This line specifically **/
<ContactList className="contactList" />
<ContactDetail />
<AddContactModal />
</div>
);
}
}
Inside your component, you would need to use className={this.props.className} on a regular HTML tag inside of your component in order to pass the className through.
You can add your specific css file to index.js directly. (like this import './master.css'
)
According to the react documentation here the className can be applied to all DOM regular element such as <div>, <a>, ...
Does your CSS works with the regular tag <div className='contactList'>hello</div> ?
Styling React Using CSS
I had a problem with applying css file to my react component, which solved by adding a .module.css extension to my css file name. I found the answer here in w3schools

How can I import a svg file to a Vue component?

In vue single file component.I import a svg file like this:
import A from 'a.svg'
And then how can I use A in my component?
Based on the information you provided, what you can do is:
Install vue-svg-loader
npm install --save-dev vue-svg-loader
Configure webpack:
module: {
rules: [
{
test: /\.svg$/,
loader: 'vue-svg-loader', // `vue-svg` for webpack 1.x
},
],
},
Import the svg and use it as a regular component:
<template>
<nav id="menu">
<a href="...">
<SomeIcon class="icon" />
Some page
</a>
</nav>
</template>
<script>
import SomeIcon from './assets/some-icon.svg';
export default {
name: 'menu',
components: {
SomeIcon,
},
};
</script>
Reference: https://github.com/visualfanatic/vue-svg-loader
I've gotten the following to work in Vue 3. Doesn't require messing with webpack or installing any third party plugins.
<template>
<img :src="mySVG" />
</template>
<script>
export default {
name: 'App',
data(){
return {
mySVG: require('./assets/my-svg-file.svg')
}
}
}
</script>
Note: I'm aware that you cannot modify certain pieces of the SVG when using it in img src, but if you simply want to use SVG files like you would any other image, this seems to be a quick and easy solution.
If you have control over the svg file, you can just wrap it in a vue file like so:
a.vue:
<template>
<svg>...</svg>
</template>
Just require the file like this afterwards: import A from 'a.vue'
If you are using Webpack you can use the require context to load SVG files from a directory. Be aware that this will put all SVG files within your Javascript files and might bloat your code though.
As a simplified example I am using this svg component:
data() {
return {
svg: ''
};
},
props: {
name: {
type: String,
required: true
}
}
created() {
this.svg = require(`resources/assets/images/svg/${this.name}.svg`);
}
The template simply looks like this:
<template>
<div :class="classes" v-html="svg"></div>
</template>
Normally you can't simply load SVG files like that and expect them to be used with a v-html directive since you are not getting the raw output. You have to use the Webpack raw-loader so make sure you get the raw output:
{
test: /\.svg$/,
use: [
{
loader: 'raw-loader',
query: {
name: 'images/svg/[name].[ext]'
}
},
{
loader: 'svgo-loader',
options: svgoConfig
}
]
}
The example above also uses the svgo-loader since you will want to heavily optimize your SVG files if you do down this route.
Hopefully this help you or anyone else out on how to solve this without diving straight into a third-party solution to fix this.
I would just use vue-svg
Install via Vue CLI 3:
vue add svg
Input:
<img src="#/assets/logo.svg?data" />
Output:
<img src="data:image/svg+xml;base64,..." />
or this is work also...
import LogoImage from "#/assets/logo.svg?inline"
You can also use something like this:
<template>
<img :src="logo"></img>
</template>
<script>
import logo from '../assets/img/logo.svg'
export default {
data() {
return {
logo
}
}
}
</script>
This doesn't require installing external modules and works out of the box.
I like to use pug as a template engine (comes with many advantages) - if you do so, you will be able to easily include files like SVG's just by writing:
include ../assets/some-icon.svg
That's it! there is nothing else to do - I think this is an very easy and convenient way to include stuff like smaller svg's - file's easily included code is still clean!
Here you can get some more information how to include PugJS into you Vue instance https://www.npmjs.com/package/vue-cli-plugin-pug
First you need a specific loader for the component which will contain the svg
my webpack.base.config.js
module: {
rules: [
{
test: /\.svg$/,
loader: 'vue-svg-loader',
},
{
test: /\.vue$/,
use: [
{
loader: "vue-loader",
options: vueLoaderConfig
},
{
loader: "vue-svg-inline-loader",
options: { /* ... */ }
}
]
}
//.. your other rules
}
docs of vues-svg-inline-loader : https://www.npmjs.com/package/vue-svg-inline-loader
docs of vue-svg-loader : https://www.npmjs.com/package/vue-svg-loader
Next, you can initialise a vue file
<template>
<div>
<img svg-inline class="icon" src='../pathtoyourfile/yoursvgfile.svg' alt="example" />
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'logo',
data () {
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#logo{
width:20%;
}
.rounded-card{
border-radius:15px;
}
//the style of your svg
//look for it in your svg file ..
//example
.cls-1,.cls-7{isolation:isolate;}.cls-2{fill:url(#linear-gradient);}.cls-3{fill:url(#linear-gradient-2);};stroke-width:2px;}..cls-6{opacity:0.75;mix-blend-mode:multiply;}.cls-7{opacity:0.13;}.cls-8{fill:#ed6a29;}.cls-9{fill:#e2522b;}.cls-10{fill:#ed956e;}.cls-185{fill:#ffc933;}..cls-13{fill:#ffd56e;}.cls-14{fill:#1db4d8;}.cls-15{fill:#0f9fb7;}.cls-16{fill:#3ad4ed;}.cls-17{fill:#25bdde;}.cls-18{fill:#fff;}
//
</style>
Your svg fils must dont contain style tag so copy paste the style in the vue style with scoped propoerty to keep it specific to this component
you can just load you component in specific place of your app
and use it
<template>
<v-app id="app">
<logo/>
<router-view/>
</v-app>
</template>
<script>
import logo from './components/logo.vue'
export default {
name: 'App',
data(){
return {
//your data
}
},
components:{
logo //the name of the component you imported
},
}
}
</script>
<style>
#app {
font-family: 'Hellow', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #070b0f;
margin-top: 60px;
}
</style>
You can always save it as a .svg file in your /static/svg/myfile.svg (using webpack) and just use it as an image file: <img src="/static/svg/myfile.svg">. No require / import / loader needed.
+1 for #Stephan-v's solution, but here's a slightly modified approach for 2021 with Webpack 5.
Your Vue component <template/>
Option A: Single SVG file
<template>
<svg viewBox="0 0 24 24">
<use :xlink:href="require('#/assets/icons/icon.svg')"></use>
</svg>
</template>
Option B: SVG Sprite (e.g. for FeatherIcons)
<template>
<svg viewBox="0 0 24 24">
<use
:xlink:href="require('#/assets/icons/sprite.svg') + `#${iconName}`"
></use>
</svg>
</template>
<script>
export default {
props: {
// Dynamic property to easily switch out the SVG which will be used
iconName: {
type: String,
default: "star",
},
},
};
</script>
You may need a Webpack loader.
NOTE: You may not need the Webpack Loader if you're using Vue 3 (as mentioned above) or Vite. If you're using Storybook or Nuxt, you will likely still need it.
$ npm install svgo-loader -D
$ yarn add svgo-loader -D
webpack.config.js (or similar)
module.exports = {
mode: "development",
entry: "./foo.js",
output: {},
// ... other config ...
module: {
rules: [
/////////////
{
// Webpack 5 SVG loader
// https://webpack.js.org/guides/asset-modules/
// https://dev.to/smelukov/webpack-5-asset-modules-2o3h
test: /\.svg$/,
type: "asset",
use: "svgo-loader",
},
],
/////////////
},
};
Done!
I was able to get svgs loading inline via
<div v-html="svgStringHere"></div>
Where svgStringHere is a computed property that returns an svg as a string

Categories

Resources