I want to integrate a module that only support server side rendering. This is project structure.
index.js
view.js
part.js (Class component)
I can use the module in getServerSideProps method in index.js. But I want to use it in part.js since there are some content I need to pass to the module that are available in part.js.
I've tried to pass a function in getServerSideProps as a prop to the component but it doesn't allowed.
Can I run server side rendering code in react class component?
server side rendering just working on pages/ directory , you cant use it in component or ....
if you want to use It on pages/ files and its not working check 2 thing
if you have _app.jsx in your project or not
if you have __app.jsx you should define it right like this
import App from 'next/app';
const MyApp = ({ Component, pageProps }) => {
return (
<Component {...pageProps} />
);
};
MyApp.getInitialProps = async (appContext) => {
const { pageProps } = await App.getInitialProps(appContext);
const { ctx } = appContext;
return { pageProps};
};
export default MyApp;
Related
I started a project with next js and typescript. I have a main component that I call it in the index.js page I use the getStaticProps function in the main component getStaticProps returns a prop object and when I log this prop in my main component I received undefined in my console.
I want to know using the getStaticProps in the component is wrong and I have just to use that function in pages or not.
I am a newbie in next js and I would be very grateful if anyone could help me.
this is my main component
import React from 'react';
import {IMain} from "../../../../interfaces/components/IMenu/IMain";
const Main:React.FC<IMain> = (props) => {
console.log(props);
return (
<div>
</div>
);
};
export async function getServerSideProps() {
return {
props: {
data: 'ggwp'
}
};
}
export default Main;
and this is my index.js page
import Text from "./../components/ui/Text/Text";
import Button from "../components/ui/Button/Button";
import Main from "../components/Menu/Desktop/Main/Main";
const Home = () => {
return <Main/>;
};
export default Home;
getStaticProps can only be exported from a page. You can’t export it from non-page files.It will not work if you add getStaticProps as a property of the page component.
https://nextjs.org/docs/basic-features/data-fetching
Here's a possible solution:
Using a node script (like predev) to fetch your content and store it in JSON files in your project, then reference those JSON files in your component.
Posted about it here:
https://dev.to/brewhousedigital/nextjs-getstaticprops-with-components-f25
Solution
used react's useEffect() for component
and for page getStaticProps() of next.js
after combine the two will have hybrid page
I have a website built in React Js and the same one on Next Js as well.
The problem which I am facing right now is, the router seems very slow in the nextJs compare to react-router-dom, It's taking almost 2-3 seconds to change the route.
Here are the URLs where you can feel the difference between the performance by moving around different pages.
https://cutt.ly/mhbPkOE (React Router Dom) vs
https://cutt.ly/BhbPvHv (NextJs)
I had read some comments on Github where few experts are saying that It will resolve in production. but It looks same in production too.
Please have a look at the following code
_app.jsx
// import App from 'next/app'
import React from "react"
import Router from 'next/router';
import "../static/sass/application.scss";
import "bootstrap/dist/css/bootstrap.min.css";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import 'semantic-ui-css/semantic.min.css'
import { wrapper } from "../../redux/utils/store"
import App from 'next/app';
// A simple component that we created
import {LoaderOverlay} from '../components/Reusable'
class MyApp extends App {
constructor(props){
super(props)
this.state = {
isLoading: false,
}
Router.onRouteChangeStart = (url) => {
// Some page has started loading
this.setState({
isLoading: true,
}) // set state to pass to loader prop
};
Router.onRouteChangeComplete = (url) => {
// Some page has finished loading
this.setState({
isLoading: false,
}) // set state to pass to loader prop
};
Router.onRouteChangeError = (err, url) => {
this.setState({isLoading: false,})
};
};
render() {
const {Component, pageProps} = this.props
return (
<div>
{this.state.isLoading ? (
<LoaderOverlay/>
) : (
<Component {...pageProps} />
)}
</div>
)
}
}
export default wrapper.withRedux(MyApp);
_document.jsx
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage
ctx.renderPage = () =>
originalRenderPage({
// useful for wrapping the whole react tree
enhanceApp: (App) => App,
// useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
})
// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head>
<link async rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui#2.4.1/dist/semantic.min.css"/>
</Head>
<body>
<div className={'main-wrapper'}>
<Main />
</div>
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
Development mode (next dev) is much slower because the routes aren't pre-built.
All delay related to routing assuming you don't have any server side blocking data requirements via getInitialProps, getServerSideProps, should not be present when running production mode with next build followed by next start.
Not sure if you have found a fix for this yet, but I came across this article about "shallow routing". I can't see much improvement in my application when using it, but maybe it will help someone else:
https://nextjs.org/docs/routing/shallow-routing
Hey I think you are in your production mode.
That's why it is slow. But if you will host your site it will be pretty much like react only.
But then also if you want to routing fast
Then npm i next#4.2.3 --save will work fine..
to solve this issue followed the commands:
yarn build/nmp build
yarn start/npm start
I hope this will solve this issue
I want to render dynamic next.js pages with custom content / style based on the domain which requests the page.
Basically run one next.js app under multiple domains.
I know that I have to do some sort of custom routing, but don't know exactly how and how I can pass the host information to the requested page, so it fetches the matching data from a database.
You should be able to verify this in your pages/_app.jsx file static getInitialProps(context) method and use the context to verify where the request is coming from then return a flag to the component.
Example:
// pages/_app.js
import app from 'next/app';
export default class MyApp extends app {
static getInitialProps({ Component, router, ctx }) {
let pageProps = app.getInitialProps({ Component, router, ctx });
if (ctx.req.headers.host.match(/localhost/)) {
pageProps = {
...pageProps,
renderFrom: 'mydomain',
}
}
return { pageProps };
}
render() {
const { Component, pageProps } = this.props;
return (
<section id="app">
<Component {...pageProps} />
</section>
);
}
}
Note that I call app.getInitialProps to mimic the next/app component behaviour as in the source code here
In your pages/index.js you will have access to props.renderFrom and there you can display data.
// pages/index.js
import React from 'react'
const Home = props => (
<div>
Rendering content for domain: {props.renderFrom}
</div>
)
export default Home
Since you're verifying where the request comes from in _app.js this property will be available in all your containers (pages) so you can have the same routing for your application and just render data differently.
Tip: You could also use next-routes to manage the routing for the application, it's better than the out next comes with, and in here you have a custom server where you can manage your traffic as well.
Hopefully this helps you and points you in the right direction.
Here’s an example of hosting multiple domains on the same Next.js site (while maintaining multiple languages and static site generation/SSG), using Next.js’ i18n system:
https://github.com/tomsoderlund/nextjs-multi-domain-locale
According to next.js documentation, if you want to customize <App>, you have to create a pages/_app.js page, then put your modifications inside.
Still, in their example there is some code, and I don't know what's its purpose:
import React from 'react'
import App, { Container } from 'next/app'
export default class MyApp extends App {
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {}
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps }
}
render () {
const { Component, pageProps } = this.props
return (
<Container>
<Component {...pageProps} />
</Container>
)
}
}
Is this the minimal form? Does this example changes the initial behavior?
In other words, is this code sufficient to extends the original app:
import React from 'react'
import App from 'next/app'
export default class MyApp extends App {}
Yes, what you have there won't change anything and is the minimum to extend App (I've tested this).
I think the reason they've included the overridden getInitialProps and render methods in the documentation is because these are likely the places that you'd want to add customizations to and the code in these is needed if you are overriding them.
For example, if you override getInitialProps but don't return the result of Component.getInitialProps(ctx) (in this case Component is the current page component, like ./pages/index.js) then your page components won't have initial props set.
I have a react component that conditionally imports a module. The reason is if the module is imported normally at the top of the file, this breaks another project's webpack build that depends on this component because it cannot process the imported module.
I have solved this issue with es6 dynamic imports - however, the problem now is that every instance of the component re-imports the module. If I have 100 components on 1 page, it'll import that module 100 times, making it horribly inefficient and slowing page load times.
What would be the proper way to only import it once, then have the rest of all component instances reference that 1 dynamically imported module?
Here's my component:
import React from "react"
export default class Link extends React.Component {
state = {
gatsbyLink: null
}
...
componentDidMount() {
if (GLOBAL_FLAG) {
import("gatsby").then(({ Link }) => {
this.setState({
gatsbyLink: Link
})
})
}
}
render() {
const { gatsbyLink } = this.state;
const GatsbyLink = gatsbyLink ? gatsbyLink : "";
...
return (<GatsbyLink {...}>...</GatsbyLink>)
}
}
I'm not sure dynamically imported modules are cached. If they aren't you could export a promise that resolves a dynamically imported gatsby if the flag is set.
You will still have to import and call it in every component where you use gatsby, but it will not dynamically import the module every time.
const conditionallyResolveGatsby = () => {
// You could reject as well
return GLOBAL_FLAG ? import('gatsby') : Promise.resolve();
};
export default conditionallyResolveGatsby();
You could also try to use require.