1

I have error 404 not found when refresh page with dynamic routes ini next js, my structure page is like below:

pages
  [storeName]
     summaries.jsx
     [store-insight].jsx

when I'm in [store-insight].jsx I need the query in url to be used in hitting an api. for example www.url.com/storName/10, I use the 10 in an api body.

*Note: when I refresh the page from localhost, everything is fine.

here is the code in [store-insight].jsx:

  import { useRouter } from 'next/router';
  import { useEffect, useState } from 'react';
  import { BackButton } from '../../components/button/BackButton';
  import Navbar from '../../components/Navbar';
  import { useSelector } from 'react-redux';
  import { StoreInsightHeader } from '../../components/storeInsight/StoreInsightHeader';
  import { KeyValueInsight } from '../../components/storeInsight/KeyValueInsight';
  import { StoreInsightSummaryChart } from '../../components/storeInsight/StoreInsightSummaryChart';

  const StoreInsight = () => {
    const { back, query } = useRouter();
    const router = useRouter();

    const {
      store,
      filterReport,
      revenuInsight,
      featuresInsight,
      productInsight,
      browsingInsight,
      operationalGraph,
    } = useSelector((store) => store);
    // const { detailStore } = store;
    // const { name, country_code, location } = detailStore;

    const [storeDetail, setStoreDetail] = useState({});

    const storeDetails = () => {
      const splitted = query['store-insight']?.split('&');
      setStoreDetail((prev) => {
        return {
          ...prev,
          id: splitted[0],
          storeName: splitted[1],
          storeLocation: splitted[2],
          storeLogo: splitted[3],
        };
      });
    };

    useEffect(() => {
      if (query['store-insight']?.length > 0) storeDetails();
    }, [query, storeDetail?.id]);

    return (
      <>
        <div className='bg-white'>
          <Navbar storeLogo={storeDetail?.storeLogo} />
        </div>
        <div className='m-6 flex flex-1 flex-row items-center space-x-3'>
          <BackButton
            onClick={() => {
              router.push({
                pathname: `/${query?.storeName}/summaries`,
                query: { date: filterReport?.filter },
              });

              localStorage.removeItem('storeDetail');
            }}
            className={'h-3 w-3'}
          />
          <label className='text-[10px] font-bold'>
            Back to Account Level Insights
          </label>
        </div>
        <div className='bg-white p-4 rounded-lg mx-4'>
          <StoreInsightHeader
            storeName={`${storeDetail?.storeName} ${storeDetail?.storeLocation}`}
          />
          <KeyValueInsight />
          <StoreInsightSummaryChart />
        </div>
      </>
    );
  };

  export default StoreInsight;

also used in <KeyValueInsight /> component ini [store-insight].jsx page like below:

import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
  setKeyInsight,
  setValueCreated,
} from '../../features/InsightV2/storeMetricSlice';
import { key_value_insight } from '../../resource/dummy-data';
import { getStoreMetric } from '../../services/insightV2/storeMetric';
import { KeyValueInsightCard } from '../card/KeyValueInsightCard';
import BrowsingInterestSkeleton from '../skeleton/BrowsingInterest';
import { convertInputPrice } from '../../helper/priceConverter';

export const KeyValueInsight = () => {
  const { query } = useRouter();
  const dispatch = useDispatch();
  const { store, filterReport, storeMetric } = useSelector((store) => store);
  const { filter, custom_date } = filterReport;
  const { key_insight, value_created } = storeMetric;

  const [loading, setLoading] = useState(false);
  const [storeDetail, setStoreDetail] = useState({});

  const storeDetails = () => {
    const splitted = query['store-insight']?.length && query['store-insight']?.split('&');

    setStoreDetail((prev) => {
      return {
        ...prev,
        id: splitted[0],
        storeName: splitted[1],
        storeLocation: splitted[2],
        storeLogo: splitted[3],
      };
    });
  };

  const currency = () => {
    if (storeDetail?.storeName === 'al-ikhsan') {
      return `MYR`;
    } else {
      return `SGD`;
    }
  };

  const fetchData = async () => {
    try {
      setLoading(true);
      if (filter === 'custom') {
        const { data } = await getStoreMetric({
          days: filter,
          storeId: storeDetail?.id,
          customStart: custom_date?.custom_start,
          customeEnd: custom_date?.custom_end,
        });

        if (data) {
          dispatch(setKeyInsight(data?.key_insight));
          dispatch(setValueCreated(data?.value_created));
        }
      } else {
        const { data } = await getStoreMetric({
          days: filter,
          storeId: storeDetail?.id,
        });

        if (data) {
          dispatch(setKeyInsight(data?.key_insight));
          dispatch(setValueCreated(data?.value_created));
        }
      }
    } catch (error) {
      console.log('store metric chart log <<<<<<', error);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (query['store-insight']?.length > 0) storeDetails();
  }, [query]);

  useEffect(() => {
    if (storeDetail?.id) fetchData();
  }, [storeDetail?.id, filter, custom_date]);

  return (
    <div className='grid grid-cols-2 mt-4 gap-x-4'>
      <div className='p-4 rounded-lg border'>
        <div className='font-semibold text-xs mb-4'>Key Insights</div>
        {loading ? (
          <BrowsingInterestSkeleton />
        ) : (
          <div className='grid text-center grid-cols-4 gap-x-4'>
            <KeyValueInsightCard
              title={'Capture'}
              value={key_insight?.capture?.value || 'WIP'}
            />
            <KeyValueInsightCard
              title={'Browsing'}
              value={key_insight?.browsing?.value || 'WIP'}
            />
            <KeyValueInsightCard
              title={'Leads'}
              value={key_insight?.leads?.value || 'WIP'}
            />
            <KeyValueInsightCard
              title={'Conversion'}
              value={key_insight?.conversion?.value || 'WIP'}
            />
          </div>
        )}
      </div>
      <div className='p-4 rounded-lg border'>
        <div className='font-semibold text-xs mb-4'>Value Created</div>
        {loading ? (
          <BrowsingInterestSkeleton />
        ) : (
          <div className='grid text-center grid-cols-4 gap-x-4'>
            <KeyValueInsightCard
              title={'Shoppers Served'}
              value={
                convertInputPrice(`${value_created?.shoppers_served?.value}`) ||
                'WIP'
              }
            />
            <KeyValueInsightCard
              title={'Time Saved'}
              value={
                convertInputPrice(`${value_created?.time_saved?.value}`) +
                ` min`
              }
            />
            <KeyValueInsightCard
              title={'Shoppers Acquired'}
              value={value_created?.shoppers_acquired?.value || 'WIP'}
            />
            <KeyValueInsightCard
              title={'Sales Generated'}
              value={
                `${currency()} ${parseFloat(
                  value_created?.sales_generated?.value,
                ).toFixed()}.00` || 'WIP'
              }
            />
          </div>
        )}
      </div>
    </div>
  );
};

1 Answer 1

0

I've found the solution for my problem, maybe anyone who got same error can try this solution. I rename the [store-insight].jsx to [storeinsight].jsx and it worked. I guess next doesn't allow to have - in dynamic page.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.