Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

549
Visualizações
nextjs getServerSideProps show loading

I am using getServerSideProps in pages/post/index.js:

import React from "react";
import Layout from "../../components/Layout";

function Post({ post }) {
  console.log("in render", post);
  return (
    <Layout title={post.name}>
      <pre>{JSON.stringify(post, undefined, 2)}</pre>
    </Layout>
  );
}

export async function getServerSideProps({ query }) {
  return fetch(
    `${process.env.API_URL}/api/post?id=${query.id}`
  )
    .then(result => result.json())
    .then(post => ({ props: { post } }));
}

export default Post;

When I directly load /post/2 it works as expected but when I go from /posts to /post/2 by clicking on a link:

<Link
  as={`/post/${post.id}`}
  href={`/post?id=${post.id}`}
>

It looks like nothing happens for 2 seconds (the api delay) and then the content shows. I can see in the network tab that _next/data/development/post/9.json is being loaded by fetchNextData.

I would like to show a loading spinner when I move from one route to another using next/Link but I can't find any documentation on getServerSideProps that allows me to do this.

When I directly go to /post/:id I'd like the data to be fetched server side and get a fully rendered page (works) but when I then move to another route the data should be fetched from the client (works). However; I would like to have a loading indicator and not have the UI freeze up for the duration of the data request.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You can use nprogress in your _app.js

import NProgress from 'nprogress';
import "nprogress/nprogress.css";
import Router from 'next/router';

NProgress.configure({
  minimum: 0.3,
  easing: 'ease',
  speed: 800,
  showSpinner: false,
});

Router.events.on('routeChangeStart', () => NProgress.start());
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());

or dynamic import to _app.js to reduce bundle size

ProgessBar.js

import Router from 'next/router';
import NProgress from 'nprogress';
import "nprogress/nprogress.css";

NProgress.configure({
    minimum: 0.3,
    easing: 'ease',
    speed: 500,
    showSpinner: false,
});

Router.events.on('routeChangeStart', () => NProgress.start());
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());

export default function () {
    return null;
}

_app.js

import dynamic from 'next/dynamic';
const ProgressBar = dynamic(() => import('components/atoms/ProgressBar'), { ssr: false });

const App = () => {
   ...
   return <>
       ...
       <ProgressBar />
   </>
}
over 4 years ago · Santiago Trujillo Relatório

0

Here is an example using hooks.

pages/_app.js

import Router from "next/router";

export default function App({ Component, pageProps }) {
  const [loading, setLoading] = React.useState(false);
  React.useEffect(() => {
    const start = () => {
      console.log("start");
      setLoading(true);
    };
    const end = () => {
      console.log("findished");
      setLoading(false);
    };
    Router.events.on("routeChangeStart", start);
    Router.events.on("routeChangeComplete", end);
    Router.events.on("routeChangeError", end);
    return () => {
      Router.events.off("routeChangeStart", start);
      Router.events.off("routeChangeComplete", end);
      Router.events.off("routeChangeError", end);
    };
  }, []);
  return (
    <>
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        <Component {...pageProps} />
      )}
    </>
  );
}
over 4 years ago · Santiago Trujillo Relatório

0

**Here is how I did it in NextJs with Material UI and nprogress**

import '../styles/globals.css';
import { useEffect, useState } from 'react';
import Router from 'next/router';
import NProgress from 'nprogress';

import { useStyles } from '../src/utils';
import { CircularProgress } from '@material-ui/core';

NProgress.configure({ showSpinner: false });

function MyApp({
  Component,
  pageProps
 
}) {
  const classes = useStyles();
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) jssStyles.parentElement.removeChild(jssStyles);

    const start = () => {
      console.log('start');
      NProgress.start();
      setLoading(true);
    };
    const end = () => {
      console.log('findished');
      NProgress.done();
      setLoading(false);
    };

    Router.events.on('routeChangeStart', start);
    Router.events.on('routeChangeComplete', end);
    Router.events.on('routeChangeError', end);
    return () => {
      Router.events.off('routeChangeStart', start);
      Router.events.off('routeChangeComplete', end);
      Router.events.off('routeChangeError', end);
    };
  }, []);
  return (
    <>
       {loading ? (
          <div className={classes.centered}>
            <CircularProgress size={25} color='primary' />
          </div>
        ) : (
        <Component {...pageProps} />
       )}
    </>
  );
}

export default MyApp;

Result: enter image description here

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda