May need an apprioate loader React-redux.js - react-redux

I keep getting this error whenever I am trying to create a validation system that goes into local storage. The error shows as follows.
./src/store/actions/authActions.js 44:42
Module parse failed: Unexpected token (44:42)
You may need an appropriate loader to handle this file type.
| if (response.error) {// show error message in alert
| } else {
> _response$data = response?.data, _userDetails = _response$data.userDetails;
| localStorage.setItem('user', JSON.stringify(_userDetails));
| dispatch(setUserDetails(_userDetails));
This occured when I changed "response.data" to response?.data" but neither option has allowed me to be able to load into local storage.
My code goes as follows:
authactions.js:
import * as api from '../../api';
export const authActions = {
SET_USER_DETAILS: 'AUTH.SET_USER_DETAILS'
};
export const getActions = (dispatch) => {
return {
//history as navigate object
login: (userDetails, navigate) => dispatch(login(userDetails, navigate)),
register: (userDetails, navigate) =>
dispatch(register(userDetails, navigate)),
};
};
const setUserDetails = (userDetails) => {
return {
type: authActions.SET_USER_DETAILS,
userDetails,
};
};
const login = (userDetails, navigate) => {
return async (dispatch) => {
const response = await api.login(userDetails);
console.log(response);
if (response.error) {
// show error message in alert
} else {
const { userDetails } = response?.data;
localStorage.setItem('user', JSON.stringify(userDetails));
dispatch(setUserDetails(userDetails));
navigate("/dashboard");
}
};
};
const register = (userDetails, navigate) => {
return async (dispatch) => {
const response = await api.register(userDetails);
console.log(response);
if (response.error) {
// show error message in alert
} else {
const { userDetails } = response?.data;
localStorage.setItem('user', JSON.stringify(userDetails));
dispatch(setUserDetails(userDetails));
navigate("/dashboard");
}
};
};
These are my current dependecies:
"dependencies": {
"#emotion/react": "^11.8.2",
"#emotion/styled": "^11.8.1",
"#mui/material": "^5.5.1",
"#mui/styled-engine-sc": "^5.4.2",
"#mui/system": "^5.5.1",
"#reduxjs/toolkit": "^1.8.0",
"#testing-library/jest-dom": "^5.16.2",
"#testing-library/react": "^12.1.4",
"#testing-library/user-event": "^7.2.1",
"axios": "^0.26.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^6.2.2",
"react-scripts": "^2.1.3",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.4.1",
"styled-components": "^5.3.3"

Related

apollo graphql network errors

I have tried to resolve this network errors but it has no possible and I do not know what is causing this. This is my apollo server index:
const mongoose = require('mongoose')
const {ObjectId} = require('mongodb')
const { createServer } = require('http')
const { execute, subscribe } = require('graphql')
const { SubscriptionServer } = require('subscriptions-transport-ws')
const { makeExecutableSchema } = require ('#graphql-tools/schema')
const express = require('express')
const { ApolloServer } = require('apollo-server-express')
const {resolvers,typeDefs} = require('./graphql')
const jwt = require('jsonwebtoken')
const {onConnect,onDisconnect} = require('./controllers/User')
require('dotenv').config()
const graphqlUploadExpress = require('graphql-upload/graphqlUploadExpress.js')
const { EventEmitter } = require('events')
const { PubSub } =require('graphql-subscriptions')
const { RedisPubSub } =require('graphql-redis-subscriptions')
const Redis = require('ioredis')
const
{
ApolloServerPluginDrainHttpServer,
ApolloServerPluginLandingPageGraphQLPlayground,
ApolloServerPluginLandingPageLocalDefault
} = require('apollo-server-core')
const { WebSocketServer} = require('ws')
const {useServer } = require('graphql-ws/lib/use/ws')
const path = require('path')
const bodyParser = require('body-parser')
const biggerEventEmitter = new EventEmitter();
biggerEventEmitter.setMaxListeners(0);
const options = {
host: process.env.REDIS_DOMAIN_NAME,
port: process.env.PORT_NUMBER,
password:process.env.REDIS_PASSWORD,
retryStrategy: times => {
// reconnect after
return Math.min(times * 50, 2000);
}
};
const pubsub = process.env.NODE_ENV === 'development' ? new PubSub({eventEmitter: biggerEventEmitter}) : new RedisPubSub({
publisher: new Redis(options),
subscriber: new Redis(options)
});
mongoose.connect(process.env.BBDD,
{},(err,_)=>
{
if(err)
{
console.log("Error de conexion")
}
else
{
console.log("Conexion Base de datos Correcta")
server()
}
})
async function server()
{
const app = express()
const httpServer = createServer(app)
const schema = makeExecutableSchema({ typeDefs, resolvers })
const PORT = process.env.APP_PORT
const getDynamicContext = async (ctx, msg, args) => {
if (ctx.connectionParams.authToken) {
const user = jwt.verify(ctx.connectionParams.authToken.replace("Bearer ", ""),process.env.KEY);
return { user, pubsub};
}
return { user: null };
};
const wsServer = new WebSocketServer(
{
server: httpServer,
path: '/graphql'
})
const serverCleanup = useServer({
schema,
context: (ctx, msg, args) => {
return getDynamicContext(ctx, msg, args)
},
onConnect: async (ctx) => {
console.log('onConnect');
let connectionParams = ctx.connectionParams
try
{
if (connectionParams.authToken)
{
const user = jwt.verify(connectionParams.authToken.replace("Bearer ", ""),process.env.KEY)
await onConnect(user.id,pubsub)
return { user , pubsub}
}
}
catch(error)
{
throw new Error('Missing auth token!')
}
},
async onDisconnect(context)
{
console.log('onDisconnect');
try
{
if(context.connectionParams&&context.connectionParams.authToken)
{
const user = jwt.verify(context.connectionParams.authToken.replace("Bearer ", ""),process.env.KEY)
await onDisconnect(user.id,pubsub)
}
}
catch(error)
{
/* throw new Error('Missing context!') */
}
}, }, wsServer)
const server = new ApolloServer(
{
schema,
persistedQueries:false,
context: async ({ req ,connection }) =>
{
let authorization = req.headers.authorization
try
{
if(authorization)
{
user = jwt.verify(authorization.replace("Bearer ", ""),process.env.KEY)
return{
user,
pubsub
}
}
}
catch (error)
{
throw new Error("Token invalido");
}
},
csrfPrevention: true,
cache: 'bounded',
plugins: [ApolloServerPluginDrainHttpServer({ httpServer }),
ApolloServerPluginLandingPageLocalDefault({ embed: true }),
{
async serverWillStart() {
return {
async drainServer() {
await serverCleanup.dispose();
},
};
},
}]
})
app.use(graphqlUploadExpress())
await server.start()
server.applyMiddleware({ app })
httpServer.listen(process.env.PORT||4000, () => {
console.log(
`Server is now running on http://localhost:${process.env.PORT||4000}${server.graphqlPath}`,
);
});
}
And this is my apollo client config:
import {ApolloClient,createHttpLink,defaultDataIdFromObject,InMemoryCache,split} from '#apollo/client'
import {WebSocketLink} from '#apollo/client/link/ws'
import { getMainDefinition } from '#apollo/client/utilities'
import { setContext } from "apollo-link-context"
import {createUploadLink} from 'apollo-upload-client'
import {getToken, getUpdatedTokenApi} from '../utils/auth'
import { GraphQLWsLink } from '#apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';
import { from, HttpLink } from '#apollo/client';
import { RetryLink } from '#apollo/client/link/retry';
import { disableFragmentWarnings } from 'graphql-tag';
disableFragmentWarnings()
const type = () =>
{
if(window.location.pathname.startsWith(`/${process.env.ADMIN_DEV}`))
{
return 'admin'
}
else
{
return null
}
}
const link = (e)=>
{
switch (e) {
case 1:
return 'https://unglo.herokuapp.com/graphql'
case 2:
return 'http://localhost:4000/graphql'
default:
break;
}
}
const ws_Link = (e)=>
{
switch (e) {
case 1:
return 'wss://unglo.herokuapp.com/graphql'
case 2:
return 'ws://localhost:4000/graphql'
default:
break;
}
}
import { onError } from "#apollo/client/link/error";
// Log any GraphQL errors or network error that occurred
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
);
if (networkError) console.log(`[Network error]: ${networkError}`);
});
const token = getToken(type())
const updatedToken = getUpdatedTokenApi()
const httpLink = new createUploadLink({
uri: link(2),
headers: {
'Apollo-Require-Preflight': 'true',
},
});
const wsLink = new GraphQLWsLink(createClient(
{
url: ws_Link(2),
connectionParams:
{
authToken: token ? `Bearer ${token}` : updatedToken ? `Bearer ${updatedToken}` : "",
},
lazy:true,
}
))
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink,
errorLink
);
const authMiddleware = setContext((_, { headers }) =>
{
return {
headers:
{
...headers,
Authorization: token ? `Bearer ${token}` :updatedToken ? `Bearer ${updatedToken}` : "",
},
}
})
const client = new ApolloClient
({
ssrMode: true,
connectToDevTools:true,
cache: new InMemoryCache({
}),
link:authMiddleware.concat(splitLink),
})
export default client
And these are errors:
I have tried removing all apollo cliente queries and errors persists and google console dont show error details
Please if any body know about this kind of errors it shoud be helpfull

Modify value inside HOC on NextJS

I've been working on a way to set up authentication and authorization for my NextJS app, so far it was pretty easy but I've hit a wall.
I have a value that lives and is watched on a context, and I have a HOC that I need for my NextJS app to be able to use hooks with GraphQl, the issues is that I don't think I can call the context and use the value from a HOC, since it is simply not allowed.
Is there a way I can dynamically change the value on the HOC so that when the user logs in, I can then update the HOC to have the proper access token?
Some context: the user is first anonymous, whenever he/she logs in, I get an auth state change from Firebase from which I can extract the access token and add it to any future requests. But the point of the hoc is to provide next with full Graphql capabilities, the thing is that I need that hoc go listen for changes on a context state.
This is the Connection Builder:
import {
ApolloClient,
InMemoryCache,
HttpLink,
NormalizedCacheObject,
} from "#apollo/client";
import { WebSocketLink } from "#apollo/client/link/ws";
import { SubscriptionClient } from "subscriptions-transport-ws";
const connectionString = process.env.HASURA_GRAPHQL_API_URL || "";
const createHttpLink = (authState: string, authToken: string) => {
const isIn = authState === "in";
const httpLink = new HttpLink({
uri: `https${connectionString}`,
headers: {
// "X-hasura-admin-secret": `https${connectionString}`,
lang: "en",
"content-type": "application/json",
Authorization: isIn && `Bearer ${authToken}`,
},
});
return httpLink;
};
const createWSLink = (authState: string, authToken: string) => {
const isIn = authState === "in";
return new WebSocketLink(
new SubscriptionClient(`wss${connectionString}`, {
lazy: true,
reconnect: true,
connectionParams: async () => {
return {
headers: {
// "X-hasura-admin-secret": process.env.HASURA_GRAPHQL_ADMIN_SECRET,
lang: "en",
"content-type": "application/json",
Authorization: isIn && `Bearer ${authToken}`,
},
};
},
})
);
};
export default function createApolloClient(
initialState: NormalizedCacheObject,
authState: string,
authToken: string
) {
const ssrMode = typeof window === "undefined";
let link;
if (ssrMode) {
link = createHttpLink(authState, authToken);
} else {
link = createWSLink(authState, authToken);
}
return new ApolloClient({
ssrMode,
link,
cache: new InMemoryCache().restore(initialState),
});
}
This is the context:
import { useState, useEffect, createContext, useContext } from "react";
import { getDatabase, ref, set, onValue } from "firebase/database";
import { useFirebase } from "./use-firebase";
import { useGetUser } from "../hooks/use-get-user";
import { getUser_Users_by_pk } from "../types/generated/getUser";
import { getApp } from "firebase/app";
const FirebaseAuthContext = createContext<FirebaseAuthContextProps>({
authUser: null,
authState: "",
authToken: null,
currentUser: undefined,
loading: true,
login: () => Promise.resolve(undefined),
registerUser: () => Promise.resolve(undefined),
loginWithGoogle: () => Promise.resolve(undefined),
loginWithMicrosoft: () => Promise.resolve(undefined),
});
export const FirebaseAuthContextProvider: React.FC = ({ children }) => {
const [loading, setLoading] = useState<boolean>(true);
const [authUser, setAuthUser] = useState<User | null>(null);
const { data } = useGetUser(authUser?.uid || "");
const [authState, setAuthState] = useState("loading");
const [authToken, setAuthToken] = useState<string | null>(null);
const currentUser = data?.Users_by_pk;
// ...
const authStateChanged = async (user: User | null) => {
if (!user) {
setAuthUser(null);
setLoading(false);
setAuthState("out");
return;
}
const token = await user.getIdToken();
const idTokenResult = await user.getIdTokenResult();
const hasuraClaim = idTokenResult.claims["https://hasura.io/jwt/claims"];
if (hasuraClaim) {
setAuthState("in");
setAuthToken(token);
setAuthUser(user);
} else {
// Check if refresh is required.
const metadataRef = ref(
getDatabase(getApp()),
"metadata/" + user.uid + "/refreshTime"
);
onValue(metadataRef, async (data) => {
if (!data.exists) return;
const token = await user.getIdToken(true);
setAuthState("in");
setAuthUser(user);
setAuthToken(token);
});
}
};
useEffect(() => {
const unsubscribe = getAuth().onAuthStateChanged(authStateChanged);
return () => unsubscribe();
}, []);
const contextValue: FirebaseAuthContextProps = {
authUser,
authState,
authToken,
currentUser,
loading,
login,
registerUser,
loginWithGoogle,
loginWithMicrosoft,
};
return (
<FirebaseAuthContext.Provider value={contextValue}>
{children}
</FirebaseAuthContext.Provider>
);
};
export const useFirebaseAuth = () =>
useContext<FirebaseAuthContextProps>(FirebaseAuthContext);
This is the HOC:
export const withApollo =
({ ssr = true } = {}) =>
(PageComponent: NextComponentType<NextPageContext, any, {}>) => {
const WithApollo = ({
apolloClient,
apolloState,
...pageProps
}: {
apolloClient: ApolloClient<NormalizedCacheObject>;
apolloState: NormalizedCacheObject;
}) => {
let client;
if (apolloClient) {
// Happens on: getDataFromTree & next.js ssr
client = apolloClient;
} else {
// Happens on: next.js csr
// client = initApolloClient(apolloState, undefined);
client = initApolloClient(apolloState);
}
return (
<ApolloProvider client={client}>
<PageComponent {...pageProps} />
</ApolloProvider>
);
};
const initApolloClient = (initialState: NormalizedCacheObject) => {
// Make sure to create a new client for every server-side request so that data
// isn't shared between connections (which would be bad)
if (typeof window === "undefined") {
return createApolloClient(initialState, "", "");
}
// Reuse client on the client-side
if (!globalApolloClient) {
globalApolloClient = createApolloClient(initialState, "", "");
}
return globalApolloClient;
};
I fixed it by using this whenever I have an update on the token:
import { setContext } from "#apollo/client/link/context";
const authStateChanged = async (user: User | null) => {
if (!user) {
setAuthUser(null);
setLoading(false);
setAuthState("out");
return;
}
setAuthUser(user);
const token = await user.getIdToken();
const idTokenResult = await user.getIdTokenResult();
const hasuraClaim = idTokenResult.claims["hasura"];
if (hasuraClaim) {
setAuthState("in");
setAuthToken(token);
// THIS IS THE FIX
setContext(() => ({
headers: { Authorization: `Bearer ${token}` },
}));
} else {
// Check if refresh is required.
const metadataRef = ref(
getDatabase(getApp()),
"metadata/" + user.uid + "/refreshTime"
);
onValue(metadataRef, async (data) => {
if (!data.exists) return;
const token = await user.getIdToken(true);
setAuthState("in");
setAuthToken(token);
// THIS IS THE FIX
setContext(() => ({
headers: { Authorization: `Bearer ${token}` },
}));
});
}
};

React Hook useEffect has some missing dependencies

I tried to run a program, but I got this warning message: Line 75:8: React Hook useEffect has missing dependencies: 'client' and 'loading'. Either include them or remove the dependency array react-hooks/exhaustive-deps
This is my Code
const UserList = ({ setSelectedUsers }) => {
const { client } = useChatContext();
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(false);
const [listEmpty, setListEmpty] = useState(false);
const [error, setError] = useState(false);
useEffect(() => {
const getUsers = async () => {
if(loading) return;
setLoading(true);
try {
const response = await client.queryUsers(
{ id: { $ne: client.userID } },
{ id: 1 },
{ limit: 8 }
);
if(response.users.length) {
setUsers(response.users);
} else {
setListEmpty(true);
}
} catch (error) {
setError(true);
}
setLoading(false);
}
if(client) getUsers()
}, []);
You can get rid of the warning by // eslint-disable-next-line react-hooks/exhaustive-deps above the useEffect dependency. useEffect sometimes suggests useless dependencies that should not be actually added in dependency array
useEffect(() => {
const getUsers = async () => {
if(loading) return;
setLoading(true);
try {
const response = await client.queryUsers(
{ id: { $ne: client.userID } },
{ id: 1 },
{ limit: 8 }
);
if(response.users.length) {
setUsers(response.users);
} else {
setListEmpty(true);
}
} catch (error) {
setError(true);
}
setLoading(false);
}
if(client) getUsers()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);```

CreateAsyncThunk is no working when I refresh the page

I'm trying to practise createAsyncThunk with reduxjs/tookit. When I first fetch the data from the api it works and I can render the data. However, when I refresh the page I get "TypeError: Cannot read properties of undefined (reading 'memes')" error and can't get it worked anymore. I looked up for some info and thought passing dispatch as useEffect dependency would help but it didn't. When I open Redux Devtools extension => diff = I can clearly see that I fetched the data, promise fulfilled and everything is fine. I try to log allMemes to console and it shows an empty object.
store.js
import { configureStore } from "#reduxjs/toolkit";
import memeSlice from "./features/getAllMemes/displayAllMemesSlice";
const store = configureStore({
reducer:{
memes:memeSlice
}
});
export default store;
DisplaySlice.js
import { createSlice, createAsyncThunk } from "#reduxjs/toolkit";
export const loadAllMemes = createAsyncThunk("getMemes/loadAllMemes", async () => {
try {
const response = await fetch("https://api.imgflip.com/get_memes");
const data = await response.json();
return data;
}
catch (error) {
console.log(error)
}
})
export const memeSlice = createSlice({
name:"getMemes",
initialState: {
isLoading:false,
hasError:false,
allMemes:{},
},
extraReducers: {
[loadAllMemes.pending]:(state, action) => {
state.isLoading = true;
},
[loadAllMemes.fulfilled]:(state, action) => {
state.allMemes = action.payload;
state.isLoading = false;
},
[loadAllMemes.rejected]:(state, action) => {
state.hasError = true;
}
}
})
export default memeSlice.reducer;
export const selectAllMemes = state => state.memes.allMemes;
displayAllMemes.js
import React , {useEffect} from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { loadAllMemes, selectAllMemes } from './displayAllMemesSlice';
export default function DisplayAllMemes() {
const allMemes = useSelector(selectAllMemes)
const dispatch = useDispatch()
useEffect(() => {
dispatch(loadAllMemes())
console.log(allMemes)
}, [dispatch])
return (
<div>
{allMemes.data.memes.map(item => (
<h1>{item.id}</h1>
))}
</div>
)
}
import { createSlice, createAsyncThunk } from "#reduxjs/toolkit";
export const loadAllMemes = createAsyncThunk("memes/getAllMemes", async () => {
try {
const response = await fetch("https://api.imgflip.com/get_memes");
const data = await response.json();
return data;
} catch (error) {
console.log(error);
}
});
export const memeSlice = createSlice({
name: "memes",
initialState: {
isLoading: false,
hasError: false,
allMemes: {},
},
extraReducers: {
[loadAllMemes.pending]: (state, action) => {
state.isLoading = true;
},
[loadAllMemes.fulfilled]: (state, action) => {
const { data, success } = action.payload;
state.allMemes = data;
state.isLoading = false;
},
[loadAllMemes.rejected]: (state, action) => {
state.hasError = true;
},
},
});
export const {} = memeSlice.actions;
export default memeSlice.reducer;
-- root reducer
import { combineReducers } from "redux";
import memes_slice from "./memes_slice";
const reducer = combineReducers({
memes: memes_slice,
});
export default reducer;
-- Component
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { loadAllMemes } from "../../app/memes_slice";
function Memes() {
const { allMemes } = useSelector((state) => state.memes);
const dispatch = useDispatch();
useEffect(() => {
dispatch(loadAllMemes());
}, [dispatch]);
console.log(allMemes.memes);
return <div>Memes</div>;
}
export default Memes;

How to add antd to Nextjs

I create a project base on with-ant-design-less and then try to add sass to project. I change the following files:
next.config.js:
/* eslint-disable */
const withSass = require("#zeit/next-sass");
const withLess = require("#zeit/next-less");
const lessToJS = require("less-vars-to-js");
const fs = require("fs");
const path = require("path");
// Where your antd-custom.less file lives
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, "./assets/antd-custom.less"), "utf8")
);
module.exports = withSass({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: "[folder]_[local]___[hash:base64:5]",
},
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
},
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
const origExternals = [...config.externals];
config.externals = [
(context, request, callback) => {
if (request.match(antStyles)) return callback();
if (typeof origExternals[0] === "function") {
origExternals[0](context, request, callback);
} else {
callback();
}
},
...(typeof origExternals[0] === "function" ? [] : origExternals),
];
config.module.rules.unshift({
test: antStyles,
use: "null-loader",
});
}
return config;
},
}),
});
package.json
{
"name": "with-ant-design-less",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"#zeit/next-less": "^1.0.1",
"#zeit/next-sass": "^1.0.1",
"antd": "^3.5.4",
"babel-plugin-import": "^1.7.0",
"less": "3.0.4",
"less-vars-to-js": "1.3.0",
"next": "latest",
"null-loader": "2.0.0",
"react": "^16.7.0",
"sass": "^1.26.3",
"react-dom": "^16.7.0"
},
"license": "ISC",
"devDependencies": {
"#types/node": "^13.13.1",
"typescript": "^3.8.3"
}
}
but when I run the project I get the following error:
[ error ] ./pages/index.module.scss
To use Next.js' built-in Sass support, you first need to install `sass`.
Run `npm i sass` or `yarn add sass` inside your workspace.
Although I'm looking for better solution to setup the project because in this way all the style will be in one big chunk that cause performance issue.
Any idea? Thanks
next.config.js:
const withPlugins = require('next-compose-plugins');
const withCss = require('#zeit/next-css');
const withSass = require('#zeit/next-sass');
const withLess = require('#zeit/next-less');
const lessToJS = require('less-vars-to-js');
const fs = require('fs');
const path = require('path');
const lessThemeVariablesFilePath = './static/ant-theme-variables.less';
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, lessThemeVariablesFilePath), 'utf8'),
);
const lessNextConfig = {
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables,
},
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
const origExternals = [...config.externals];
config.externals = [
(context, request, callback) => {
if (request.match(antStyles)) return callback();
if (typeof origExternals[0] === 'function') {
origExternals[0](context, request, callback);
} else {
callback();
}
},
...(typeof origExternals[0] === 'function' ? [] : origExternals),
];
config.module.rules.unshift({
test: antStyles,
use: 'null-loader',
});
}
return config;
},
};
const sassNextConfig = {
cssModules: true,
cssLoaderOptions: {
localIdentName: '[path]___[local]___[hash:base64:5]',
},
};
module.exports = withPlugins([
[withLess, lessNextConfig],
[withSass, sassNextConfig],
]);
babel config:
module.exports = {
presets: ['next/babel'],
plugins: [
['import', { libraryName: 'antd', style: true }],
],
};
I use sass, less and css. it depends on your requirement. and you can add your custom variables in an static file as I did.
hope be helpful.
So, for people who came here just for the basic addition, you can add antd to your nextjs app by installing antd
npm i antd
and then you can add the antd styles to your
_app.js file
after your global styles:
import 'antd/dist/antd.css'

Resources