garmeeh / next-seo

Next SEO is a plug in that makes managing your SEO easier in Next.js projects.
MIT License
7.64k stars 393 forks source link

next-seo and static export #420

Closed arecvlohe closed 4 years ago

arecvlohe commented 4 years ago

Hi! Thanks for this great library. Really makes implementing SEO much nicer experience in nextjs.

I have been running into the issue, and I have seen others online have too, with getting the next/head to render during static export. Take a look at this example I have in my repo. I am using both defaultseo and nextseo in my application:

When you use twitter bot though to hit my site,curl -A twitterbot https://nativesintech.org/, which is deployed on Netlify you get this:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <meta name="next-head-count" content="2">
    <link rel="preload" href="/_next/static/css/ecc0a033a92e666bee9d.css" as="style">
    <link rel="stylesheet" href="/_next/static/css/ecc0a033a92e666bee9d.css">
    <link rel="preload" href="/_next/static/Zbtlt1X-d_NZwcBxT56OA/pages/_app.js" as="script">
    <link rel="preload" href="/_next/static/Zbtlt1X-d_NZwcBxT56OA/pages/index.js" as="script">
    <link rel="preload" href="/_next/static/runtime/webpack-c212667a5f965e81e004.js" as="script">
    <link rel="preload" href="/_next/static/chunks/framework.e84fa698c7ee940652bd.js" as="script">
    <link rel="preload" href="/_next/static/chunks/commons.cd9ca553a70fe5f8c3dd.js" as="script">
    <link rel="preload" href="/_next/static/runtime/main-7b03bd62f37bf56324f5.js" as="script">
    <link rel="preload" href="/_next/static/chunks/d7eeaac4.3f569e732de615d9c700.js" as="script">
    <link rel="preload" href="/_next/static/chunks/1bfc9850.887f7df523c5d16858ab.js" as="script">
    <link rel="preload" href="/_next/static/chunks/2dd74a00a17be0b52824d74a7d86990d7929597b.c273a7619e6ffdf25c19.js" as="script">
    <style data-styled="active" data-styled-version="5.1.1"></style>
    <link href="/_next/static/Zbtlt1X-d_NZwcBxT56OA/pages/about.js" rel="prefetch" as="script">
    <link href="/_next/static/Zbtlt1X-d_NZwcBxT56OA/pages/awesome.js" rel="prefetch" as="script">
    <link href="/_next/data/Zbtlt1X-d_NZwcBxT56OA/awesome.json" rel="prefetch" as="fetch">
    <link href="/_next/static/chunks/2dd74a00a17be0b52824d74a7d86990d7929597b.c273a7619e6ffdf25c19.js" rel="prefetch" as="script">
</head>

However when you visit the site directly from the browser, the meta tags are there. Probably after the client loads:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1.0, width=device-width">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
    <link rel="manifest" href="/site.webmanifest">
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
    <meta name="msapplication-TileColor" content="#da532c">
    <meta name="theme-color" content="#ffffff">
    <meta name="viewport" content="width=device-width">
    <meta charset="utf-8">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@nativesintech">
    <meta name="twitter:creator" content="@nativesintech">
    <meta property="og:url" content="https://nativesintech.org">
    <meta property="og:type" content="website">
    <meta property="og:description" content="Natives in Tech is a coalition of Native and non-Native developers who seek to empower and support Native communities around the world through open source technology.">
    <meta property="og:image" content="https://nativesintech.org/computer.svg">
    <meta property="og:site_name" content="Natives in Tech">
    <meta name="robots" content="index,follow">
    <meta name="googlebot" content="index,follow">
    <meta property="og:title" content="Natives in Tech - Home">
    <meta name="next-head-count" content="13">
    <link rel="preload" href="/_next/static/css/df6e1cfe5adcb6b6a5bc.css" as="style">
    <link rel="stylesheet" href="/_next/static/css/df6e1cfe5adcb6b6a5bc.css">
    <link rel="preload" href="/_next/static/P0j0W46UIgvGtVUkLCL2E/pages/_app.js" as="script">
    <link rel="preload" href="/_next/static/P0j0W46UIgvGtVUkLCL2E/pages/index.js" as="script">
    <link rel="preload" href="/_next/static/runtime/webpack-c212667a5f965e81e004.js" as="script">
    <link rel="preload" href="/_next/static/chunks/framework.e84fa698c7ee940652bd.js" as="script">
    <link rel="preload" href="/_next/static/chunks/commons.cd9ca553a70fe5f8c3dd.js" as="script">
    <link rel="preload" href="/_next/static/chunks/b09aa9a2f34099e120f7ebbca6f085242c4b95c7.32735d6c9942150c4363.js" as="script">
    <link rel="preload" href="/_next/static/runtime/main-bfcc3bea00f174e64a0a.js" as="script">
    <link rel="preload" href="/_next/static/chunks/d7eeaac4.d324e210ff22d45b3e8b.js" as="script">
    <link rel="preload" href="/_next/static/chunks/1bfc9850.b73ab998a53e7be230b4.js" as="script">
    <link rel="preload" href="/_next/static/chunks/8c1824ab4fc0751018f53dc7f22c4ccfa1d4d1d4.6dfb2b6531ddbf121abf.js" as="script">
    <style data-styled="active" data-styled-version="5.1.1"></style>
    <link href="/_next/static/P0j0W46UIgvGtVUkLCL2E/pages/about.js" rel="prefetch" as="script">
    <link href="/_next/static/P0j0W46UIgvGtVUkLCL2E/pages/awesome.js" rel="prefetch" as="script">
    <link href="/_next/data/P0j0W46UIgvGtVUkLCL2E/awesome.json" rel="prefetch" as="fetch">
    <link href="/_next/static/chunks/8c1824ab4fc0751018f53dc7f22c4ccfa1d4d1d4.6dfb2b6531ddbf121abf.js" rel="prefetch" as="script">
</head>

I am confused as to what I need to do in order to get next-seo, and thus SEO in general, to work with static export when the export itself does not hold all the meta tags in it.

Things I have checked are:

garmeeh commented 4 years ago

Hey @arecvlohe from what I can see the meta tags seem to be rendering correctly 🤔

When you disabled JS or view page source you can see what the server is rendering it as and they are present.

This is what I get:

<head>
  <meta charSet="utf-8" />
  <meta name="viewport" content="initial-scale=1.0, width=device-width" />
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
  <link rel="manifest" href="/site.webmanifest" />
  <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
  <meta name="msapplication-TileColor" content="#da532c" />
  <meta name="theme-color" content="#ffffff" />
  <meta name="viewport" content="width=device-width" />
  <meta charSet="utf-8" />
  <meta name="twitter:card" content="summary_large_image" />
  <meta name="twitter:site" content="@nativesintech" />
  <meta name="twitter:creator" content="@nativesintech" />
  <meta property="og:url" content="https://nativesintech.org" />
  <meta property="og:type" content="website" />
  <meta property="og:description"
    content="Natives in Tech is a coalition of Native and non-Native developers who seek to empower and support Native communities around the world through open source technology." />
  <meta property="og:image" content="https://nativesintech.org/computer.svg" />
  <meta property="og:site_name" content="Natives in Tech" />
  <meta name="robots" content="index,follow" />
  <meta name="googlebot" content="index,follow" />
  <meta property="og:title" content="Natives in Tech - Home" />
  <meta name="next-head-count" content="13" />
  <link rel="preload" href="/_next/static/css/df6e1cfe5adcb6b6a5bc.css" as="style" />
  <link rel="stylesheet" href="/_next/static/css/df6e1cfe5adcb6b6a5bc.css" />
  <link rel="preload" href="/_next/static/P0j0W46UIgvGtVUkLCL2E/pages/_app.js" as="script" />
  <link rel="preload" href="/_next/static/P0j0W46UIgvGtVUkLCL2E/pages/index.js" as="script" />
  <link rel="preload" href="/_next/static/runtime/webpack-c212667a5f965e81e004.js" as="script" />
  <link rel="preload" href="/_next/static/chunks/framework.e84fa698c7ee940652bd.js" as="script" />
  <link rel="preload" href="/_next/static/chunks/commons.cd9ca553a70fe5f8c3dd.js" as="script" />
  <link rel="preload" href="/_next/static/chunks/b09aa9a2f34099e120f7ebbca6f085242c4b95c7.32735d6c9942150c4363.js"
    as="script" />
  <link rel="preload" href="/_next/static/runtime/main-bfcc3bea00f174e64a0a.js" as="script" />
  <link rel="preload" href="/_next/static/chunks/d7eeaac4.d324e210ff22d45b3e8b.js" as="script" />
  <link rel="preload" href="/_next/static/chunks/1bfc9850.b73ab998a53e7be230b4.js" as="script" />
  <link rel="preload" href="/_next/static/chunks/8c1824ab4fc0751018f53dc7f22c4ccfa1d4d1d4.6dfb2b6531ddbf121abf.js"
    as="script" />
</head>
arecvlohe commented 4 years ago

This is my mistake. On netlify's website they say:

Our built-in prerendering service will cache prerendered pages for between 24 and 48 hours; this is not adjustable.

I was viewing them too early probably.

re: https://docs.netlify.com/site-deploys/post-processing/prerendering/#set-up-prerendering

garmeeh commented 4 years ago

Ah good to know. Thanks for letting me know 😄

jofelipe commented 4 years ago

Hi!

First of all, thank you for this library. It helps a lot to deal with SEO in Next.js applications.

So, I'm facing the same issue with my application, but mine is deployed at Vercel.

I'm using Static Generation (getStaticProps), and when I see my source code using browser inspect (client side), I can see all meta tags generated:

<title>História criada em produção... - Peakseekers</title>
<meta name="robots" content="index,follow" />
<meta name="googlebot" content="index,follow" />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="Peakseekers" />
<meta name="description" content="Get inspired by Jonathan's story of summit on Pico das Agulhas Negras." />
<meta property="og:url" content="https://peakseekers.app/jow/historia-criada-em-producao-ASuC9svome5yZIkwFA7m" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2020-10-05T00:28:44.806Z" />
<meta property="article:author" content="https://peakseekers.app/jow/" />
<meta property="article:tag" content="Peakseekers" />
<meta property="article:tag" content="Mountains" />
<meta property="article:tag" content="Pico das Agulhas Negras" />
<meta property="og:title" content="História criada em produção..." />
<meta property="og:description" content="Get inspired by Jonathan's story of summit on Pico das Agulhas Negras." />
<meta property="og:image" content="https://firebasestorage.googleapis.com/v0/b/peakseekers-b6502.appspot.com/o/qnipHwhnsphQ5VuJJjiP7Bqf2yJ3%2F02cc5f04-89aa-4426-9346-0563a9ba0bc5.jpg?alt=media" />
<meta property="og:image:alt" content="História criada em produção..." />

But in the static page generated by Next, only tags configured in the DefaultSeo component appears:

<title>Peakseekers - Peakseekers</title><meta name="robots" content="index,follow" />
<meta name="googlebot" content="index,follow" />
<meta name="description" content="An platform developed especially for explorers to share stories about their summits in mountains around the world." />
<meta property="og:url" content="https://peakseekers.app/" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Peakseekers - Peakseekers" />
<meta property="og:description" content="An platform developed especially for explorers to share stories about their summits in mountains around the world." />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="Peakseekers" />

My _app.js code with DefaultSeo component is:

<DefaultSeo
                title="Peakseekers"
                titleTemplate="%s - Peakseekers"
                description="An platform developed especially for explorers to share stories about their summits in mountains around the world."
                openGraph={{
                    type: 'website',
                    locale: 'en_US',
                    url: 'https://peakseekers.app/',
                    site_name: 'Peakseekers',
                }}
            />

And this page, has this configuration:

<NextSeo
                title={story?.title}
                description={
                    language === 'pt'
                        ? `Se inspire com a história de conquista de ${story?.author.name} em ${story?.mountain.name};`
                        : `Get inspired by ${story?.author.name}'s story of summit on ${story?.mountain.name}.`
                }
                openGraph={{
                    title: story?.title,
                    description:
                        language === 'pt'
                            ? `Se inspire com a história de conquista de ${story?.author.name} em ${story?.mountain.name};`
                            : `Get inspired by ${story?.author.name}'s story of summit on ${story?.mountain.name}.`,
                    url: storyUrl,
                    type: 'article',
                    article: {
                        publishedTime: story?.created_at,
                        authors: [authorUrl],
                        tags: [
                            'Peakseekers',
                            'Mountains',
                            story?.mountain.name,
                        ],
                    },
                    images: [
                        {
                            url: story?.images[0],
                            alt: story?.title,
                        },
                    ],
                }}
            />

Any ideia of what is going on? Any help will be apreciated.

Also, the URL: https://peakseekers.app/jow/historia-criada-em-producao-ASuC9svome5yZIkwFA7m

Thank you!

jofelipe commented 4 years ago

So, I figure it out what happened.

In other issues, people said that it's related to providers/hooks that returns null if there is no data. So I checked my providers and I found the mistake... It was not related to providers but I had a conditional render of components in my _app.js, like this:

const MyApp = ({ Component, pageProps }) => {
  const [isMounted, setIsMounted] = useState(false)
  const darkMode = useDarkMode(true)
  const theme = darkMode.value ? darkTheme : lightTheme

  useEffect(() => {
    setIsMounted(true)
  }, [])

  return (
    <ThemeProvider theme={theme}>
      <button onClick={darkMode.enable}>DARK MODE</button>
      <button onClick={darkMode.disable}>LIGHT MODE</button>
      {isMounted && <Component {...pageProps} />}
    </ThemeProvider>
  )
}

Basically, the component as rendered with useEffect. So in this case, next-seo could not set their metatags. Also, you will have some problems with Next SSG.

I hope it helps someone :)

nabiltkarim commented 3 years ago

@jofelipe How'd you manage to fix it? Facing the same problem here. In the static page generated by Next, it's only showing the default SEO configs.

jofelipe commented 3 years ago

@jofelipe How'd you manage to fix it? Facing the same problem here. In the static page generated by Next, it's only showing the default SEO configs.

Hi! In my case the problem was a conditional render with useEffect in _app.js, for darkmode theme purposes. I had to remove it.

Make sure if your _app.js doesn't have something similar, related to hooks or any lib.

gstrobl commented 2 years ago

@nabiltkarim did you fixed it? I'm facing the same problem.