everybody
I'm working with nextjs and now I'm starting to use microfrontends
I'm trying to implement a repository container for this I use #module-federation/nextjs-mf
I want to put localization and fonts in the repository container to begin with
This is my next.config.js in container repo
const NextFederationPlugin = require('#module-federation/nextjs-mf')
const { i18n } = require('./next-i18next.config')
module. Exports = {
reactStrictMode: true,
i18n,
webpack(config, options) {
const { isServer } = options
const location = isServer ? 'ssr' : 'chunks'
config.plugins.push(
new NextFederationPlugin({
name: 'home',
filename: 'static/chunks/remoteEntry.js',
remotes: {
container: `container#http://localhost:3000/_next/static/${location}/remoteEntry.js`,
app2: `app2://localhost:3001/_next/static/${location}/remoteEntry.js`,
},
exposes: {
'./font': './src/font/segoeui-light.woff2'
},
shared: {},
})
)
return config
},
}
And this is index.tsx in container repo pages/index.tsx
export default function Home() {
const { t: translate } = useTranslation('test-app')
return (
<>
<h1>Container index Page</h1>
<h2>{translate('test')}</h2>
<Link href="/app2">app2</Link>
</>
)
}
Application 2 runs locally on port 3001, and the container on port 3000
But I have errors with the container launch, maybe I'm doing something wrong, where is my mistake?
Related
I have used wagmi for wallet connect and using next js , the wallet trigger and open extension of coinbase in local but when we deploy it on sever it always tell to install even though it is already installed. I am sharing my connection tried using both alchemy and infura provider but not working . Any idea anybody.shared pic the wallet is installed but still it ask to install
import {
configureChains,
createClient,
goerli,
mainnet,
WagmiConfig,
} from "wagmi";
import { alchemyProvider } from "wagmi/providers/alchemy";
import { infuraProvider } from "wagmi/providers/infura";
import { publicProvider } from "wagmi/providers/public";
import { ReactNode } from "react";
import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet";
import { MetaMaskConnector } from "wagmi/connectors/metaMask";
import { WalletConnectConnector } from "wagmi/connectors/walletConnect";
interface WalletProviderInterface {
children: ReactNode;
}
const WalletProvider = ({ children }: WalletProviderInterface) => {
const { chains, provider, webSocketProvider } = configureChains(
[mainnet],
[
alchemyProvider({
apiKey: process.env.NEXT_PUBLIC_ALCHEMY_KEY || "",
}),
infuraProvider({ apiKey: process.env.NEXT_PUBLIC_INFURA_KEY || "" }),
]
);
const connectors = [
new MetaMaskConnector({
chains,
options: {
shimDisconnect: true,
shimChainChangedDisconnect: false,
},
}),
new CoinbaseWalletConnector({
chains,
options: {
appName: `test app`,
jsonRpcUrl: `https://ethmainnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_KEY}`,
},
}),
new WalletConnectConnector({
chains,
options: {
// alchemyId:process.env.NEXT_PUBLIC_ALCHEMY_KEY,
qrcode: true,
},
}),
];
const client = createClient({
autoConnect: true,
connectors,
provider,
webSocketProvider,
});
return <WagmiConfig client={client}>{children}</WagmiConfig>;
};
export default WalletProvider;
I'm using Prismic and NextJS for the first time.
What I'm trying to is make it so when the user goes to the base url for the page localhost:3000/ in dev something will load. /About and /Pricing are working fine the base url doesn't work.
import { GetStaticPaths, GetStaticProps } from 'next'
import { SliceZone } from '#prismicio/react'
import * as prismicH from "#prismicio/helpers";
import { createClient, linkResolver } from '../../prismicio'
import { components } from '../../slices'
interface HomePageProps {
page: any
}
const HomePage = (props:HomePageProps) => {
return <SliceZone slices={props.page.data.slices} components={components} />
}
export default HomePage
interface HomePageStaticProps {
params: any
previewData:any
}
export async function getStaticProps(props:HomePageStaticProps) {
console.log("DOES NOT FIRE FOR localhost:3000")
const client = createClient({ previewData:props.previewData })
const params = props.params;
const uid = params?.pagePath?.[params.pagePath.length - 1] || "home";
const page = await client.getByUID("page", uid);
return {
props: {
page,
},
}
}
export const getStaticPaths: GetStaticPaths = async () => {
const client = createClient();
const pages = await client.getAllByType("page");
const paths = pages.map((page) => prismicH.asLink(page, linkResolver)) as string[];
console.log(paths) // [ '/pricing', '/about', '/' ]
return {
paths,
fallback: false,
};
}
or to simplify it further
[[...pagePath]].tsx fails when going to localhost:3000/ but does not fail on localhost:3000/about or localhost:3000/pricing.
import { GetStaticPaths, GetStaticProps } from 'next'
interface HomePageProps {
page: string
}
const HomePage = (props:HomePageProps) => {
return <>{props.page}</>
}
export default HomePage
interface HomePageStaticProps {
params: any
previewData:any
}
export async function getStaticProps(props:HomePageStaticProps) {
const params = props.params;
const uid = params?.pagePath?.[params.pagePath.length - 1] || "home";
//const page = await client.getByUID("page", uid);
return {
props: {
page:uid,
},
}
}
export const getStaticPaths: GetStaticPaths = async () => {
const paths = [ '/pricing', '/about', '/' ];
return {
paths,
fallback: false,
};
}
As far as I can see your'e not fetching the right way. In order to to have a clean project I would recommend to use a const var where you can determine between dev and production enviorenment. To do so you can simply create a file for example: constants.js containing the following:
export const baseurl = process.env.NODE_ENV === "production"
? process.env.NEXT_PUBLIC_DOMAIN // <-- your domain on live
: "http://localhost:3000"; // localhost on dev
Now with this you automatically have localhost on your dev. Notice that you need http:// which your'e missing at the moment. Now the next example shows you how to fetch something on your root / by entering the following code:
import { baseurl } from "../utils/constants"; // <-- importing the constant
// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
export async function getStaticProps() {
// Call an external API endpoint to get posts.
// You can use any data fetching library
const res = await fetch(`${baseurl}/api/posts`)
const posts = await res.json()
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts,
},
}
}
If you are using Create-T3-App
https://github.com/t3-oss/create-t3-app
then
your next.config.mjs will default to this as of Nov 7, 2022
const config = {
reactStrictMode: true,
swcMinify: true,
i18n: {
locales: ["en"],
defaultLocale: "en",
},
};
export default config;
remove
const config = {
reactStrictMode: true,
swcMinify: true,
//i18n: {
// locales: ["en"],
// defaultLocale: "en",
//},
};
export default config;
This will make default "/" pathing work, if you require i18n, I'm sorry I can't help.
This is part of my next js project. This website is running perfectly on localhost but when i deploy it on vercel, the /blogs/book/chapter page is giving me file not found enter image description here500 error.
Hosted Page - Website
Source Code - GitHub
Dynamic Routing Folder Structure
Page Structure
chapter.js
import fs from "fs";
import path from "path";
import Head from "next/head";
import DefaultErrorPage from "next/error";
import { useRouter } from "next/router";
import matter from "gray-matter";
import { marked } from "marked";
import styles from "../../../../styles/blog/Chapter.module.css";
import { capitalise } from "../../../../components/blog/Capitalise";
import BlogPostBottom from "../../../../components/blog/BlogPostBottom";
export default function Chapter({ book, chapter, frontmatter, content }) {
// Destructuring
const { description } = frontmatter;
// Router Variable
const router = useRouter();
// If fallback then show this
if (router.isFallback) {
// if (router.isFallback || !book || !chapter || !content) {
return <div>Loading...</div>;
}
if (!book || !chapter || !content || !frontmatter) {
return (
<div>
<DefaultErrorPage statusCode={404} />
</div>
);
}
return (
<div className={styles.bookChapter}>
<Head>
<title>{`${capitalise(chapter)} | ${capitalise(
book
)} | Blog | Manav Goyal`}</title>
<meta
name="description"
content={`Read Blog about this book ${book} covering chapter ${chapter} of topics ${description}`}
/>
</Head>
<h1>{`${capitalise(chapter)} - ${capitalise(book)}`}</h1>
<section
className={styles.bookChapterContent}
dangerouslySetInnerHTML={{ __html: marked(content) }}
></section>
<BlogPostBottom slug={`/blog/${book}`} />
</div>
);
}
export async function getStaticPaths() {
return {
paths: [{ params: { book: "css", chapter: "bootstrap" } }],
// paths: [],
fallback: true,
};
}
// Web crawlers, won't be served a fallback and instead the path will behave as in fallback: 'blocking'
// fallback: true is not supported when using `next export`
export async function getStaticProps({ params }) {
const { book, chapter } = params;
let chapterPost = null;
try {
chapterPost = await fs.promises.readFile(
path.join(`posts/${book}/${chapter}.md`),
"utf-8"
);
} catch (err) {}
const { data: frontmatter, content } = matter(chapterPost);
return {
props: {
book,
chapter,
frontmatter,
content,
},
// redirect: {
// destination: `/blog/${book}`,
// permanent: false,
// },
// revalidate: 1,
};
}
Chapter.defaultProps = {
book: "css",
chapter: "bootstrap",
frontmatter: { description: "CSS", id: "1" },
content: "Error",
};
Posts Folder Structure
Posts Folder Structure
Error
Console
Vercel Function Log
How would I go about precaching all the pages of my nextjs app using next-pwa?. Let's say I have the following pages:
/
/about
/posts
I want all of them to be precached so that they are all available offline once the app has been loaded the first time. At the moment I'm using a custom webpack config to copy the .next/build-manifest.json file over to public/build-manifest. Then once the app loads the first time, I register an activated handler that fetches the build-manifest.json file and then adds them to the cache. It works but it seems like a roundabout way of achieving it, and it depends somewhat on implementation details. How would I accomplish the same in a more canonical fashion?
At the moment, my next.config.js file looks like this
const pwa = require('next-pwa')
const withPlugins = require('next-compose-plugins')
const WebpackShellPlugin = require('webpack-shell-plugin-next')
module.exports = withPlugins([
[
{
webpack: (config, { isServer }) => {
if (isServer) {
config.plugins.push(
new WebpackShellPlugin({
onBuildExit: {
scripts: [
'echo "Transfering files ... "',
'cp -r .next/build-manifest.json public/build-manifest.json',
'echo "DONE ... "',
],
blocking: false,
parallel: true,
},
})
)
}
return config
},
},
],
[
pwa,
{
pwa: {
dest: 'public',
register: false,
skipWaiting: true,
},
},
],
])
And my service worker hook looks like this
import { useEffect } from 'react'
import { Workbox } from 'workbox-window'
export function useServiceWorker() {
useEffect(() => {
if (
typeof window !== 'undefined' &&
'serviceWorker' in navigator &&
(window as any).workbox !== undefined
) {
const wb: Workbox = (window as any).workbox
wb.addEventListener('activated', async (event) => {
console.log(`Event ${event.type} is triggered.`)
console.log(event)
const manifestResponse = await fetch('/build-manifest.json')
const manifest = await manifestResponse.json()
const urlsToCache = [
location.origin,
...manifest.pages['/[[...params]]'].map(
(path: string) => `${location.origin}/_next/${path}`
),
`${location.origin}/about`,
...manifest.pages['/about'].map((path: string) => `${location.origin}/_next/${path}`),
`${location.origin}/posts`,
...manifest.pages['/posts'].map((path: string) => `${location.origin}/_next/${path}`),
]
// Send that list of URLs to your router in the service worker.
wb.messageSW({
type: 'CACHE_URLS',
payload: { urlsToCache },
})
})
wb.register()
}
}, [])
}
Any help is greatly appreciated. Thanks.
I am trying to insert an image into my Next.js v.10 application using the new built-in Image component.
Here is the code:
import * as React from "react";
import Image from "next/image";
export const TestImage = () => {
return (
<Image
src="/images/dummy-rectangle-image.png"
alt="about"
unsized
/>
);
};
My images are located in the public/static/images folder.
next.config.js:
const withPlugins = require("next-compose-plugins");
const withCSS = require("#zeit/next-css");
const withSass = require("#zeit/next-sass");
const withBundleAnalyzer = require("#next/bundle-analyzer");
const nextRuntimeDotenv = require("next-runtime-dotenv");
const withConfig = nextRuntimeDotenv({ public: ["API_URL", "API_KEY"] });
const nextConfig = {
analyzeServer: ["server", "both"].includes(process.env.BUNDLE_ANALYZE),
analyzeBrowser: ["browser", "both"].includes(process.env.BUNDLE_ANALYZE),
bundleAnalyzerConfig: {
server: {
analyzerMode: "static",
reportFilename: "../bundles/server.html",
},
browser: {
analyzerMode: "static",
reportFilename: "../bundles/client.html",
},
},
publicRuntimeConfig: {
PROXY_MODE: process.env.PROXY_MODE,
API_URL: process.env.API_URL,
API_KEY: process.env.API_KEY,
STATIC_PATH: process.env.STATIC_PATH,
},
};
module.exports = withConfig(
withPlugins([[withCSS], [withSass], [withBundleAnalyzer]], nextConfig)
);
Result:
Request URL:
localhost:3000/_next/image?url=%2Fimages%2Fblack-arrow.png&w=768&q=75
Status Code: 500 Internal Server Error
It seems something is wrong with the Next.js configuration to recognize the right path to the image. I read documentation tips but seems nothing helps in my case.
What is the right way for the usage of Image component in Next.js v.10?
If your image is located in the public/static/images folder, then your <Image /> component needs to have an src of src="/static/images/image-name.png". This is because anything in the public folder is served directly, including directories.