I receive this error when use hooks in component from remote app when
enter image description here
i use now nextjs13 with module federations
how to resolve this
enter code here
my component remote app
'use client'
import { useState } from 'react'
export default function Button() {
const [count, setCount] = useState(0)
return (
<div>
<button onClick={() => setCount(count + 1)}>adicionar</button>
<h1>{count}</h1>
</div>
)
}
my component in host
'use client'
import dynamic from 'next/dynamic'
import React, { useState } from 'react'
const RemoteComponent = dynamic({
loader: async () => {
const { default: RemoteComponent } = await import('front_login/Button')
return () => <RemoteComponent />
},
})
export default function Auth() {
return (
<>
<RemoteComponent />
</>
)
}
my next-config.js in host
const { NextFederationPlugin } = require('#module-federation/nextjs-mf')
/** #type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
experimental: {
appDir: true,
},
webpack: (config, options) => {
const { isServer } = options
Object.assign(config.experiments, { topLevelAwait: true })
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
}
config.plugins.push(
new NextFederationPlugin({
name: 'front_gateway',
remotes: {
front_login: `front_login#${process.env.FRONT_LOGIN}/_next/static/${
isServer ? 'ssr' : 'chunks'
}/remoteEntry.js`,
},
filename: 'static/chunks/remoteEntry.js',
shared: {
'styled-components': {
requiredVersion: false,
eager: true,
singleton: true,
},
},
}),
)
return config
},
}
module.exports = nextConfig
my next config in remote app
/** #type {import('next').NextConfig} */
const { NextFederationPlugin } = require('#module-federation/nextjs-mf')
const nextConfig = {
output: 'standalone',
experimental: {
appDir: true,
},
webpack: (config, options) => {
const { isServer } = options
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
}
config.plugins.push(
new NextFederationPlugin({
name: 'front_login',
remotes: {
front_gateway: `front_gateway#${
process.env.FRONT_GATEWAY
}/_next/static/${isServer ? 'ssr' : 'chunks'}/remoteEntry.js`,
},
filename: 'static/chunks/remoteEntry.js',
exposes: {
'./Button': './src/app/components/Button/button.tsx',
'./Doidao': './src/app/doidao/page.tsx',
},
shared: {
'styled-components': {
singleton: true,
eager: true,
requiredVersion: false,
},
},
}),
)
return config
},
}
module.exports = nextConfig
Please i need help to fix this
When use remote component in remote app, work with success but in host not working
Related
I have an app with nextjs 13 pages dire.
i am using zoom web sdk for embed the meetings. it works just fine in the dev mode.
the proplem:
when i build the app everything working except that zoom component not showing up after build,
when visiting the /meeting page the component didn't exist.
const ZoomCall = dynamic(() => import("#components/Zoom/ZoomCall"), {
ssr: false,
loading: () => "Loading...",
});
the ZoomCall
import { useEffect } from "react";
import dynamic from "next/dynamic";
import { ZoomMtg } from "#zoomus/websdk";
import ZoomMtgEmbedded from "#zoomus/websdk/embedded";
import ZoomInputs from "./ZoomInputs";
import { useState } from "react";
import useTranslation from "next-translate/useTranslation";
export default function ZoomCall({
user,
meetingNumber,
setMeetingnumber,
passWord,
setMeetingPassword,
}) {
const { t } = useTranslation();
const [isComponentMounted, setIsComponentMounted] = useState(false);
const signatureEndpoint = "/api/zoom/signature";
const role = 0;
useEffect(() => {
ZoomMtg.setZoomJSLib("https://source.zoom.us/1.9.1/lib", "/av");
ZoomMtg.preLoadWasm();
ZoomMtg.prepareJssdk();
}, []);
function getSignature(e) {
e.preventDefault();
fetch(signatureEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
meetingNumber: meetingNumber,
role: role,
}),
})
.then((res) => res.json())
.then((response) => {
startMeeting(response.signature);
})
.catch((error) => {
console.error(error);
});
}
function startMeeting(signature) {
let meetingSDKElement = document.getElementById("meetingSDKElement");
const client = ZoomMtgEmbedded.createClient();
// document.getElementById("zmmtg-root").style.display = "block";
client.init({
debug: true,
zoomAppRoot: meetingSDKElement,
language: "en-US",
customize: {
meetingInfo: [
"topic",
"host",
"mn",
"pwd",
"telPwd",
"invite",
"participant",
"dc",
"enctype",
],
toolbar: {
buttons: [
{
text: "Custom Button",
className: "CustomButton",
onClick: () => {
console.log("custom button");
},
},
],
},
},
});
client.join({
sdkKey: process.env.NEXT_PUBLIC_ZOOM_API_KEY,
signature: signature,
meetingNumber: meetingNumber,
password: passWord,
userName: "..",
userEmail: "ah....",
});
}
return (
<div>
<div id="meetingSDKElement"></div>
<button onClick={getSignature}>Join Meeting</button>
</div>
);
}
I have moved the exports to a index file the export
import dynamic from "next/dynamic";
export default dynamic(() => import("./ZoomCall"), { ssr: false });
the issue in still
i have managed to solve this by changing the :
const ZoomCall = dynamic(() => import("#components/Zoom/ZoomCall"), {
ssr: false,
loading: () => "Loading...",
});
into
export default dynamic(() => import("./ZoomCall").then((mod) => mod.ZoomCall), {
ssr: false,
});
and it works just fine
I migrated to next.js and started to use next-i18next. I would like to know, how to make next-i18next load locales from the public folder? It works only when I place the locales folder in the root directory not in public.
i18n.json ;
{
"locales": ["en", "fr", "ar"],
"defaultLocale": "en",
"pages": {
"*": ["common"]
}
}
next.config.js ;
// next.config.js
const nextTranslate = require("next-translate");
module.exports = {
...nextTranslate(),
};
Create i18n.js file root add this code inside:
const path = require('path');
module.exports = {
i18n: {
locales: ['en', 'ru', 'tm'],
defaultLocale: 'en',
localeDetection: false,
localePath: path.resolve('./public/locales'),
},
};
and add config next.config.js file this:
const { i18n } = require('./i18n');
const nextConfig = {
reactStrictMode: true,
i18n,
};
module.exports = nextConfig;
after every page add transalition code. example: index.file
import React, { useContext, useEffect } from 'react';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useTranslation } from 'next-i18next';
import Router from 'next/router';
import { Title } from '../components';
import i18n from '../i18n';
const Home = () => {
const { t } = useTranslation('');
useEffect(() => {
if (!user) {
Router.push('/login');
}
});
return (
<>
<Title title={`${t('page.home')} | Trillo`} />
<div className="min-h-screen">Home</div>
</>
);
};
export const getServerSideProps = async ({ locale }) => (
{ props: {
...(await serverSideTranslations(
locale,
['common'],
i18n,
)),
} }
);
export default Home;
After you create these files inside public folder like this. see this and see this 2
im trying to setup nextjs 12 with ant design antd and in next.config.js when i try to setup withAntdLess it gives type error
Type '{}' is missing the following properties from type '{ esModule: boolean; sourceMap: boolean; modules: { mode: string; }; }': esModule, sourceMap, modules
although all props are optional according to next-plugin-antd-less docs
next.config.js file:
// #ts-check
// next.config.js
const withAntdLess = require('next-plugin-antd-less');
/**
* #type {import('next').NextConfig}
**/
module.exports =withAntdLess({
cssLoaderOptions: {},
// Other Config Here...
webpack(config) {
return config;
},
reactStrictMode: true,
});
I solved it using next-with-less https://github.com/elado/next-with-less
next.config.js
const withLess = require('next-with-less');
const lessToJS = require('less-vars-to-js');
const themeVariables = lessToJS(
fs.readFileSync(
path.resolve(__dirname, './public/styles/custom.less'),
'utf8'
)
);
module.exports = withLess({
...
lessLoaderOptions: {
lessOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
localIdentName: '[path]___[local]___[hash:base64:5]',
},
},
...
})
Import your custom less file on top off the file _app.jsx
import 'public/styles/custom.less';
...
Import the default Antd less file on your custom less file: (in my case public/styles/custom.less)
#import "~antd/dist/antd.less";
....
Extra notes:
If you have an old implementation of Antd, you should remove the integration in your .babelrc
[
"import",
{
"libraryName": "antd",
"libraryDirectory": "lib",
"style": true
}
],
If you have an old implementation of Antd, you should remove the integration in your webpack zone in your next.config.js
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',
});
}
I am trying to add react-responsive-carousel to my NextJS project. When i run npm run dev everything seems to be fine, however my carousel is rendered with no styles.
import { Carousel } from 'react-responsive-carousel';
import 'react-responsive-carousel/lib/styles/carousel.min.css'; // requires loader
const MyCarousel = () => {
return (
<Carousel
autoPlay
interval={2500}
showArrows={true}
>
<div>content</div>
<div>content</div>
<div>content</div>
</Carousel>
)
}
Documentation says that styles need a loader so I configures next.config.js as follows
const withLess = require('#zeit/next-less');
const withCss = require('#zeit/next-css');
const withImage = require('next-images');
const theme = require('./app/styles/antdoverrides');
module.exports = withImage(
withCss({
cssModules: true,
optimizeFonts: false,
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
importLoaders: 0,
modifyVars: {
...theme,
},
},
cssLoaderOptions: {
importLoaders: 3,
localIdentName: '[local]___[hash:base64:5]',
},
webpack5: false,
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;
},
}),
}),
);
still not getting desired result. Any hints appreciated
You need to import your styles in your _app.js file if you don't use the objects. Just in your _app make import of your styles, something like:
import "../styles/globals.css";
Also you need to npm run local or something like this, check your package.json file to run locally your project instead of build
I'm following Microsoft's Tutorial:
Deploy static-rendered Next.js websites on Azure Static Web Apps
The problem is, I'm trying to add to my next.config.js file this code:
const data = require('./utils/projectsData');
module.exports = {
trailingSlash: true,
exportPathMap: async function () {
const { projects } = data;
const paths = {
'/': { page: '/' },
};
projects.forEach((project) => {
paths[`/project/${project.slug}`] = {
page: '/project/[path]',
query: { path: project.slug },
};
});
return paths;
},
};
but my next.config.js already has some existing content:
require('dotenv').config()
const withFonts = require('next-fonts')
module.exports = withFonts({
serverRuntimeConfig: {},
trailingSlash: true,
exportPathMap: function() {
return {
'/': { page: '/' }
};
},
publicRuntimeConfig: {
API_URL: process.env.API_URL,
PORT: process.env.PORT || 3000,
PUBLISHABLE_KEY: process.env.PUBLISHABLE_KEY,
},
})
how can I combine them?
Just combine them like that?
require('dotenv').config()
const data = require('./utils/projectsData'); // Add this line
const withFonts = require('next-fonts')
module.exports = withFonts({
serverRuntimeConfig: {},
trailingSlash: true,
// And override this key
exportPathMap: async function () {
const { projects } = data;
const paths = {
'/': { page: '/' },
};
projects.forEach((project) => {
paths[`/project/${project.slug}`] = {
page: '/project/[path]',
query: { path: project.slug },
};
});
return paths;
},
publicRuntimeConfig: {
API_URL: process.env.API_URL,
PORT: process.env.PORT || 3000,
PUBLISHABLE_KEY: process.env.PUBLISHABLE_KEY,
},
})