skip to Main Content

I’m working on SEO component which needs a canonical URL.

How can I get URL of static page in Next.js with Automatic Static Optimization turned on?

6

Answers


  1. use package called next-absolute-url . It works in getServerSideProps. Since getStaticProps run on build time so dont have data available.
    can be used as

    export const getServerSideProps: GetServerSideProps = async (ctx) => {
     const { req, query } = ctx;
       const { origin } = absoluteUrl(req);      
          return {
            props: {
              canonicalUrl: `${origin}/user-listings`,
            },
          };
        };
    
    export const getStaticProps:GetStaticProps = async (ctx) => {
      return {
        props: {
          canonicalUrl: 'https://www.test.com',
        },
      };
    };
    
    Login or Signup to reply.
  2. Using useRouter from next/router you can get the pathname for the current page and use it in a <Head/> tag as following:

    import { useRouter } from "next/router";
    
    const site = "https://gourav.io";
    const canonicalURL = site + useRouter().pathname;
    
    <Head>
      <link rel="canonical" href={canonicalURL} />
    </Head>
    
    Login or Signup to reply.
  3. Building on fzembow’s comment about useRouter().asPath and GorvGoyl’s answer, here’s an implementation which manages to handle both dynamic routes and excludes anchor and query param URL extensions:

    import { useRouter } from "next/router";
    
    const CANONICAL_DOMAIN = 'https://yoursite.com';
    
    const router = useRouter();
    const _pathSliceLength = Math.min.apply(Math, [
        router.asPath.indexOf('?') > 0 ? router.asPath.indexOf('?') : router.asPath.length,
        router.asPath.indexOf('#') > 0 ? router.asPath.indexOf('#') : router.asPath.length
    ]);
    const canonicalURL= CANONICAL_DOMAIN + router.asPath.substring(0, _pathSliceLength);
    
    <Head>
      <link rel="canonical" href={ canonicalURL } />
    </Head>
    
    Login or Signup to reply.
  4. A super ugly, yet, the most adequate solution I found:

    const canonicalUrl = typeof window === 'undefined' ?
      '' :
      `${window.location.origin}/${window.location.pathname}`;
    
    Login or Signup to reply.
  5. My solution was to use new URL with router.asPath.

        const CURRENT_URL = process.env.NEXT_PUBLIC_CURRENT_SITE_URL
    
        const getCanonical = (path: string) => {
          const fullURL = new URL(path, CURRENT_URL)
          return`${fullURL.origin}${fullURL.pathname}
        }
    
        export const Page = () => {
          const router = useRouter()
          const canonical = getCanonical(router.asPath)
    
          <Head>
            <link rel="canonical" href={canonical} />
          </Head>
          <div>
          ...
          <div>
        }
    
    Login or Signup to reply.
  6. I added a canonical link tag to _app.js so that it appears on every page:

    <link
       rel="canonical"
       href={typeof window !== 'undefined' && `${window.location.origin}${useRouter().asPath}`}
       key="canonical"
    />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search