NextJS Build error: package.json does not exist at /package.json - next.js

I have been working on a NextJS application that utilizes Firebase. I have everything set up and on build I get the following error: package.json does not exist at /package.json (see the image)
build error
To give more context on this:
NextJS v^9.3.0
Firebase v^7.10.0
Target: server (by default)
My next.config.js:
const path = require('path')
const resolve = require('resolve')
const withCSS = require('#zeit/next-css')
const withImages = require('next-images')
const withFonts = require('next-fonts')
const withTM = require('next-transpile-modules')([
'*************',
'*************',
'*************'
]);
if (typeof require !== "undefined") {
require.extensions[".less"] = () => {};
require.extensions[".css"] = (file) => {};
}
module.exports =
withCSS(
withImages(
withFonts(
withTM({
webpack: (config, options) => {
config.module.rules.push({
test: /\.svg$/,
use: ['#svgr/webpack'],
});
const { dir, isServer } = options
config.externals = []
if (isServer) {
config.externals.push((context, request, callback) => {
resolve(request, { basedir: dir, preserveSymlinks: true }, (err, res) => {
if (err) {
return callback()
}
if (
res.match(/node_modules[/\\].*\.css/)
&& !res.match(/node_modules[/\\]webpack/)
&& !res.match(/node_modules[/\\]#aws-amplify/)
) {
return callback(null, `commonjs ${request}`)
}
callback()
})
})
}
return config;
},
cssLoaderOptions: {
url: false
}
})
)
)
)
I have been trying many solutions, including the following:
- I should use target server, but I have also tried with "experimental-serverless-trace" but no effect, same error persists
- Tried also "webpack-asset-relocator-loader" but it doesn't work as well. When utilized, I get the following error: "gRPC binary module was not installed".
To be honest, at this point I do not have any idea where to go from this point.
Thanks!

Related

getStatic Path not working for base URL "/" in NextJS

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.

React-responsive-carousel styles not working

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

How to precache ALL pages with next-pwa

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.

Determining the language by the path of Url

I tried to find a way to change the language by changing the site's sub-path in the next-i18next package, I searched the Internet (https://github.com/isaachinman/next-i18next/issues/32 , https://github.com/i18next/i18next-browser-languageDetector#detector-options) for an answer to this question, but it did not work. After changing the subpath in the url it is duplicated and redirects me to a page that does not exist.
my code:
// path-to-my-project/i18n.js
const NextI18Next = require('next-i18next').default;
const i18nextBrowserLanguageDetector = require('i18next-browser-languagedetector').default;
const { localeSubpaths } = require('next/config').default().publicRuntimeConfig;
const path = require('path');
module.exports = new NextI18Next({
otherLanguages: ['ru'],
defaultNS: 'common',
localeSubpaths,
localePath: path.resolve('./public/static/locales'),
use: [i18nextBrowserLanguageDetector],
});
// path-to-my-project/pages/_app.js
import '../styles/main.scss';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import Router from 'next/router';
import App from 'next/app';
import { appWithTranslation } from '../i18n';
Router.events.on('routeChangeStart', () => NProgress.start());
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());
const MyApp = ({ Component, pageProps }) => (
<Component {...pageProps} />
);
MyApp.getInitialProps = async (appContext) => ({ ...await App.getInitialProps(appContext) });
export default appWithTranslation(MyApp);
maybe I just missed something, because it's my first project on next.js, so I'm asking for help in the community and would be grateful for any help or hint.
By default next-i18next will try to detect the language to show from users browser.
Try to disable it.
const NextI18Next = require('next-i18next').default
const { localeSubpaths } = require('next/config').default().publicRuntimeConfig
const path = require('path')
module.exports = new NextI18Next({
browserLanguageDetection: false, // <---
serverLanguageDetection: false, // <---
otherLanguages: ['de'],
localeSubpaths,
localePath: path.resolve('./public/static/locales')
})
in file next.config.js i have this settings:
// path/to/project/next.config.js
const { nextI18NextRewrites } = require('next-i18next/rewrites');
const localeSubpaths = {
ru: 'ru',
};
module.exports = {
rewrites: async () => nextI18NextRewrites(localeSubpaths),
publicRuntimeConfig: {
localeSubpaths,
},
devIndicators: {
autoPrerender: false,
},
};
but there was not enough configuration for English localization, so you just need to add it:
// path/to/project/next.config.js
const { nextI18NextRewrites } = require('next-i18next/rewrites');
const localeSubpaths = {
en: 'en', // <------
ru: 'ru',
};
module.exports = {
rewrites: async () => nextI18NextRewrites(localeSubpaths),
publicRuntimeConfig: {
localeSubpaths,
},
devIndicators: {
autoPrerender: false,
},
};

Using Pa11y with Supertest

What is the best way to use Pa11y with Supertest? Something like:
describe ('my page', function () {
it ('is accessible', function () {
request (server).get ('/').expect (function ({ body }) {
// How to run Pa11y here?
});
});
})
I would suggest not using supertest at all for these accessibility test as pa11y can ping url's directly.
const pa11y = require('pa11y');
const request = require('supertest');
const mocha = require('mocha');
const { expect } = require('chai');
const server = require('./server');
const url =
process.env.NODE_ENV === 'testing'
? 'http://localhost:3000'
: 'http://example.com';
describe('my page', function() {
it('is accessible', function(done) {
pa11y(`${url}/`, function(err, results) {
expect(results.issues).to.be.empty;
done();
});
});
});

Resources