I am a Gatsby newbie and I'm following this tutorial: https://www.gatsbyjs.com/docs/creating-plugins/ to learn to create a gatsby local plugin using react-intl. I put the plugin in the plugins folder in the root of the project.
This is the demo code of the plugin (Demo Project Repo: https://github.com/85Ryan/gatsby-local-plugin-demo.git)
// ./src/wrap-page-element.js
import * as React from 'react'
import { IntlProvider } from 'react-intl'
const message = {
welcome: 'Welcome',
home: 'Home',
}
const wrapPageElement = ({ element }) => {
const locale = 'en'
return (
<IntlProvider locale={locale} key={locale} messages={message}>
{element}
</IntlProvider>
)
}
export { wrapPageElement }
// gatsby-browser.js
export { wrapPageElement } from './src/wrap-page-element'
// gatsby-ssr.js
export { wrapPageElement } from './src/wrap-page-element'
When I build the Gatsby site, it crashes with the error WebpackError: [React Intl] Could not find requiredintlobject. <IntlProvider> needs to exist in the component ancestry.
But when I publish the plugin to npm, it works fine.
Can anyone help me to find where my problem is?
Thanks!
You are re-exporting wrapPageElement a second time in your file:
// gatsby-browser.js
export { wrapPageElement } from './src/wrap-page-element'
This replaces the earlier export that included <IntlProvider />.
Related
The Problem:
I'm building a blog with Next and sanity. When navigating to /blog, i'm encountering this error in the browser:
./sanity.js:2:0
Module not found: Can't resolve '#sanity/image-url'
1 | import { createCurrentUserHook, createClient } from "next-sanity";
> 2 | import imageUrlBuilder from "#sanity/image-url";
3 |
4 | export const config = {
5 | // Find your project ID and dataset in 'sanity.json' in your studio project.
Import trace for requested module:
./pages/blog.tsx
https://nextjs.org/docs/messages/module-not-found
The folder structure is:
root
-> components
-> pages
-> post
-> [slug].tsx
-> index.tsx
-> blog.tsx
-> sanity subfolder
-> public
-> styles
sanity.js (config file)
The sanity config file
I have a sanity config file, which exports some helper functions. One of which, is the imageUrlBuilder function, which i'm assuming the error is coming from. Here is my sanity config file: Note: this is pulled from sanity docs.
import { createCurrentUserHook, createClient } from "next-sanity";
import imageUrlBuilder from "#sanity/image-url";
export const config = {
// config info here
};
// Set up the client for fetching data in the getProps page functions.
export const sanityClient = createClient(config);
// Builder function to combo with urlFor function.
const builder = imageUrlBuilder(sanityClient);
// Helper function to generate urls from sanity photos.
export const urlFor = (source) => {
return builder.image(source);
};
The helper function was working in a previous version, and was able to pull images from sanity and display in the document. But i'm unsure why it's causing issues with page routing.
The blog page component:
import React from "react";
import BlogPreview from "../components/BlogPreview";
import { getAllPosts } from "../queries";
import { sanityClient } from "../sanity";
import { Post } from "../typings";
interface Props {
posts: [Post];
}
// required for server-side rendering. returns 'props' object from db.
export const getServerSideProps = async () => {
let query = getAllPosts;
const posts = await sanityClient.fetch(query);
return {
props: {
posts,
},
};
};
function blog({ posts }: Props) {
return (
<div>
<div className='md:grid md:grid-cols-2'>
{posts.map((post) => {
return (
<BlogPreview
key={post._id}
title={post.title}
description={post.description}
mainImage={post.mainImage}
slug={post.slug}
/>
);
})}
</div>
</div>
);
}
export default blog;
I've tried:
Logging sanity data to the console to check for config errors.
Googling the error: Module not found: Can't resolve '#sanity/image-url'
Conclusion
I'm unsure what the issue is, and how I can potentially solve it. Would love some ideas.
Thanks in advance
It sounds like you don't have the #sanity/image-url module installed in your project.
Run this in your project directory and you should be good to go!
npm install --save #sanity/image-url
In production mode, after building, when open subpath directly, Next JS app gives 404.
For example, when I open domain.com/page, gives - 404. But, when I open domain.com/en/page it works.
My next.config.js file:
module.exports = {
i18n:{
locales:["en", "ru"],
defaultLocale: "en",
}
}
One of my page components:
import { MainLayout } from "../components/MainLayout";
import en from "../locales/en/en.js";
import ru from "../locales/ru/ru.js";
import { useRouter } from "next/router";
export default function About() {
let router = useRouter();
const { locale } = router;
const t = locale === "en" ? en : ru;
return (
<MainLayout title={"About page"}>
<div className="container">
<div className="content">
<h1>{t.about}</h1>
</div>
</div>
</MainLayout>
);
}
In your _app.js
You have to write this line;
export default appWithTranslation(YourApp);
And you should define localePath in your i18n object in next.config.js
like this :
localePath: path.resolve("./public/locales")
After you can access your translations in component or page like this;
const { t } = useTranslation('common');
I know that this is an old question, but I'm leaving this answer from stackoverflow for anyone that is having this error using Docker, in my case it was the solution to my problem.
Be sure to copy the next.config.js file in your Dockerfile:
COPY ./next.config.js /app/next.config.js
My Problem :
I expect my FirebaseProvider function to provide an object containing all functions, through the app. The problem is that all functions are well provided through my files, except my last new function : fetchTest.
Explainations :
If I click the TestPage.js button I get Uncaught TypeError: fetchTest is not a function.
I saw many posts on stackoverflow about this type of error, but none did help me. -> I think the original problem is the index.js is not called. The console.log("firebaseprovider") (in index.js) does not appear in console, yet the other files of the project in web-app/src/views/ have the same imports and exports than TestPage.
Since App.js code worked fine on all the other files, I don't know how console.log("firebaseprovider") is never displayed in the navigator console. (edit: no matter which page I go, this console.log never appears)
<FirebaseProvider> seems to not provide TestPage.js.
Do you have an idea ?
What I've tried :
placing a console.log in TestPage.js : it shows every function written in index.js but not fetchTest. It seems to not be properly exported through api object.
in TestPage.js trying console.log("api.fetchTest") : console displays undefined.
add a second testing function in index.js, whithout parameters, which just does console.log("test")
compare imports/exports and api declarations with other files in web-app/src/views/
create a handleSubmit() function in TestPage.js to not put the functions directly in return
delete node_modules and then yarn install
yarn workspace web-app build and then relaunch yarn workspace web-app start
(This is a Yarn Workspaces project containing a common/ and a web-app/ folders)
common/src/index.js:
import React, { createContext } from 'react';
import {FirebaseConfig} from 'config';
const FirebaseContext = createContext(null);
const FirebaseProvider = ({ children }) => {
console.log("firebaseprovider"); // is not displayed in the console
let firebase = { app: null, database: null, auth: null, storage:null }
if (!app.apps.length) { // I tried to comment out this line (and the '}') -> no difference
app.initializeApp(FirebaseConfig); // no difference when commented out
firebase = {
app: app,
database: app.database(),
auth: app.auth(),
storage: app.storage(),
// [ ... ] other lines of similar code
api : { // here are functions to import
fetchUser: () => (dispatch) => fetchUser()(dispatch)(firebase),
addProfile: (details) => (dispatch) => addProfile(userDetails)(dispatch)(firebase),
// [ ... ] other functions, properly exported and working in other files
// My function :
fetchTest: (testData) => (dispatch) => fetchTest(testData)(dispatch)(firebase),
}
}
}
return (
<FirebaseContext.Provider value={firebase}>
{children}
</FirebaseContext.Provider>
)
}
export { FirebaseContext, FirebaseProvider, store }
web-app/src/views/TestPage.js:
import React, { useContext } from "react";
import { useDispatch } from "react-redux";
import { FirebaseContext } from "common";
const TestPage.js = () => {
const { api } = useContext(FirebaseContext);
console.log(api); // Displays all functions in api object, but not fetchTest
const { fetchTest } = api;
const dispatch = useDispatch();
const testData = { validation: "pending" };
return <button onClick={ () => {
dispatch(fetchTest(testData)); // Tried with/without dispatch
alert("done");
}}>Test button</button>
}
export default TestPage;
web-app/src/App.js:
import React from 'react';
import { Router, Route, Switch } from 'react-router-dom';
// ... import all pages
import { Provider } from 'react-redux';
import TestPage from './views/CreateSiteNeed'; // written same way for the other pages
import { store, FirebaseProvider } from 'common';
function App() {
return (
<Provider store={store}>
<FirebaseProvider>
<AuthLoading>
<Router history={hist}>
<Switch>
<ProtectedRoute exact component={MyProfile} path="/profile" />
<!-- [ ... ] more <ProtectedRoute /> lines, form imported Pages line 3. -->
<ProtectedRoute exact component={TestPage} path="/testpage" />
</Switch>
</Router>
</AuthLoading>
</FirebaseProvider>
</Provider>
);
}
export default App;
I hope some people will find this post helpful, thanks
Here was the problem :
Firstly :
I'm using Redux, so fetchTest() has its testActions.js and testReducer.js files, which are functionnal. But I did forget to update my store.js :
// [ ... ] import all reducers
import { testReducer as testData } from '../reducers/testReducer'; // was'nt imported
const reducers = combineReducers({
auth,
usersdata,
// [ ... ] other imported reducers
testData // My test reducer
}
// The rest is a classic store.js code
Secondly :
As I'm using Yarn Workspaces, I had to compile the code in common/dist/index.js to make it accessible through the whole entire code (even for local testing).
Here is the command to compile the code (-> to include all redux edits made above) and make it accessible to web-app workspace :
yarn workspace common build && yarn workspace web-app add common#1.0.0 --force
Explanations on the second part of the command (yarn workspace web-app add common#1.0.0 --force) :
The web-app/package.json file contains { "dependencies": { ... "common":"1.0.0" ... }}
I am trying to localize pages with gatsby-plugin-intl. No problem for .js files as I described below but how should I make it for .mdx files?
import React from "react"
import { FormattedMessage, injectIntl, navigate } from "gatsby-plugin-intl"
const MyPage = ( {intl} ) => (
<Layout>
<h2><FormattedMessage id="TITLE"/></h2>
</Layout>
)
export default injectIntl(MyPage)
I am trying to make the similar logic here:
---
name: Settings
route: /documentation/settings
---
import { Playground, Props } from 'docz'
import { useIntl, Link, FormattedMessage } from "gatsby-plugin-intl"
const intl = useIntl()
## Settings
intl.formatMessage({ id: "TITLE"})
every think look right but you have an error on the mdx file
const intl = useIntl()
use the FormattedMessage components instead message
example
<FormattedMessage id="TITLE" />
or your components
<Yourcomponents title={useIntl().formatMessage({ id: "TITLE" })} />
don't use const
Here's an application running on create-react-app and Next JS
. Difference between them is CRA seems to have loaded bootstrap.mon.js and jquery.min.js while NextJS has not. I added a HEAD section to NextJS code through next/head and attempted to load both JS files. Although there were no errors, I did not see right results either.
Can someone help me understand why this happens with NextJS and what should I do to get NextJS load my application right with bootstrap and jquery
Add this snippet to your _app.js just above your return code
useEffect(() => {
import("bootstrap/dist/js/bootstrap");
}, []);
so your complete _app.js will be like this
import { useEffect } from 'react';
function MyApp({ Component, pageProps }: AppProps) {
useEffect(() => {
import("bootstrap/dist/js/bootstrap");
}, []);
return <Component {...pageProps} />
}
export default MyApp
You have to require the modules at the client-side. so you can use this
// _app.js
if (typeof window !== "undefined") {
require("jquery");
require("popper.js");
require("bootstrap/dist/js/bootstrap");
}
You can require client-side libraries in componentDidMount() after installed via npm.
import React, { Component } from 'react';
export class HomePage extends Component {
render() {
return (
<div>
Hello
</div>
);
}
componentDidMount() {
require('jquery');
require('popper');
require('bootstrap');
}
}
export default HomePage;