harlan-zw / nuxt-seo

The complete SEO solution for Nuxt.
https://nuxtseo.com
1.02k stars 63 forks source link

Nuxt Sitemap does not include the images even though the Nuxt content pages contain many images. #298

Closed Aravinda93 closed 1 week ago

Aravinda93 commented 3 weeks ago

I am developing a Nuxt content website for documentation purposes and using the Nuxt Sitemap in it.

I have created a similar repo as my original project on CodeSandBox. Can someone please have a look and provide some solutions on the automatic generation of sitemap for images in the Nuxt Content project?

I am adding the sitemap information to my /content/docs with all the markdown or .md files such as:

/content/docs/introduction/index.md:

---
title: "Introduction"
description: My Introduction to content website
sitemap:
  loc: /docs/introduction
  lastmod: 2024-08-30
  changefreq: quaterly
  priority: 0.9
___

I can generate the sitemap.xml file during the npm run generate but this generates the url only for the routes that are present in /content/docs where I have added the sitemap information to my index.md files such as this in:

<url>
    <loc>https://example.io/docs/introduction</loc>
    <lastmod>2024-08-30</lastmod>
    <changefreq>quaterly</changefreq>
    <priority>0.9</priority>
    <xhtml:link rel="alternate" href="https://example.io/docs/introduction" hreflang="x-default" />
    <xhtml:link rel="alternate" href="https://example.io/docs/introduction" hreflang="en" />
</url>

I have many images within this index.md file but these images are for some reason not included in the sitemap.xml file. I don't want to specify each image in my all .md files rather want a dynamic approach where Nuxt Content/Sitemap can automatically scan and include all images in my /content/docs so it's all included in sitemap.xml file.

I added the following:

sitemap: {   
  urls: [
    {
      loc: '/docs',
      images: [
        {
          loc: 'https://example.io/docs/introduction/image1.png',
          caption: 'My image caption',
          geoLocation: 'My image geo location',
          title: 'My image title',
          license: 'My image license',
        }
      ]
    }
  ]
},

This will add only the specified image here to my sitemap.xml file. However, I have a lot of images in different .md files within my Nuxt content /content/docs. How to include all dynamically and directly without specifying each of them here in nuxt.config.js file?

  1. I added the following by looking into the Nuxt Content Documentation
//To support and display the .md files from /content using @nuxt/content
content: {
  documentDriven: true,
  sitemap: true,
  //To get the reading time for each .md file in /content
  markdown: {
    remarkPlugins: ["remark-reading-time"],
  },
  //To build the sitemap for SEO automatically using @nuxt/sitemap
  strictNuxtContentPaths: true
},

sitemap: {
  sources: [
    '/api/__sitemap__/urls'
  ]
},

And a file in /server/api/__sitemap__/urls.ts but this also does not make any difference and I do not get my images or videos in sitemap.xml file:

import { defineEventHandler } from 'h3'
import type { ParsedContent } from '@nuxt/content/dist/runtime/types'
import { serverQueryContent } from '#content/server'
import { asSitemapUrl, defineSitemapEventHandler } from '#imports'

export default defineSitemapEventHandler(async (e) => {
  const contentList = (await serverQueryContent(e).find()) as ParsedContent[]
  return contentList
    .filter(c => c._path.startsWith('docs'))
    .map((c) => {
      return asSitemapUrl({
        loc: `/blog/${c._path.replace('docs', '')}`,
        lastmod: updatedAt
      })
    })
})
  1. As per mentioned in the Nuxt SiteMap Automatic Image Discovery i wrapped my layouts/default.vue with <main> something like this:
<!-- Page Content -->
<div class="w-full flex flex-col flex-grow">
  <main>
    <slot />
  </main>
</div>

Previously I was just using the <slot />. Even after adding the <main> when I generate the .output I don't see image-related things in sitmap.xml.

References:

  1. Nuxt Sitemap
  2. Nuxt Sitemap images
  3. CodeSandBox Reproduction of the issue

Is there any way to achieve this?

harlan-zw commented 3 weeks ago

Did you try following Automatic Image Discovery?

Aravinda93 commented 3 weeks ago

@harlan-zw Thanks a lot for the response. As per mentioned in the document i wrapped my layouts/default.vue with <main> something like this:

<!-- Page Content -->
<div class="w-full flex flex-col flex-grow">
  <main>
    <slot />
  </main>
</div>

Previously I was just using the <slot />. Even after adding the <main> when I generate the .output I don't see image related things in sitmap.xml. Do I need to do anything else as well? I have following in my nuxt.config.js:

 modules: [
    "@nuxtjs/tailwindcss",
    "unplugin-fonts/nuxt",
    "@nuxtjs/i18n",
    "@nuxt/content",
    "@nuxtjs/color-mode",
    "@nuxt/image",
    "@nuxtjs/sitemap"
  ],

  //To support and display the .md files from /content using @nuxt/content
  content: {
    documentDriven: true,
    sitemap: true,
    //To get the reading time for each .md file in /content
    markdown: {
      remarkPlugins: ["remark-reading-time"],
    },
    //To build the sitemap for SEO automatically using @nuxt/sitemap
    strictNuxtContentPaths: true
  },

Do I need to add anything for the sitemap to include automatically everything?

Aravinda93 commented 3 weeks ago

Did you try following Automatic Image Discovery?

@harlan-zw I tried the approach you mentioned but seems like its not working. Any suggestion, please?

harlan-zw commented 3 weeks ago

Sorry looks like I missed that part.

The quickest and easiest way for me to help you is by providing a reproduction, there's even already a Nuxt Content starter for you https://stackblitz.com/edit/nuxt-starter-a5qk3s?file=nuxt.config.ts

You've given me a lot of information but not a lot I can do without replicating the issue, this feature works as far as I know, there are tests in place for it.

Aravinda93 commented 3 weeks ago

@harlan-zw Thanks a lot for the response. Sorry, I should have given you the code sample. I have created a similar repo as my original project on CodeSandBox. Can you please have a look and provide some solutions on the automatic generation of sitemap for images in the Nuxt Content project?

I have my contents/images in /docs/introduction and /docs/basics and I have 3 images in my public/img repo but for some reason I do not see anything within my sitemap.xml when I run npm run generate

Aravinda93 commented 3 weeks ago

Sorry looks like I missed that part.

The quickest and easiest way for me to help you is by providing a reproduction, there's even already a Nuxt Content starter for you https://stackblitz.com/edit/nuxt-starter-a5qk3s?file=nuxt.config.ts

You've given me a lot of information but not a lot I can do without replicating the issue, this feature works as far as I know, there are tests in place for it.

@harlan-zw As per your request I have added my reproduction code here CodeSandBox if you get a chance can you please have a look and provide some solution?

harlan-zw commented 3 weeks ago

I had a look at this and it seems like the regex parsing was broken for the NuxtImg output.

I've pushed up a fix which is in v6.0.0-beta.4 of the sitmeap module, you can upgrade to it by deleting your lock file + node_modules and re-installing.

If you still have issues please use this as a reproduction https://stackblitz.com/edit/nuxt-starter-a5qk3s?file=app.vue, the codesandbox has issues running.

Aravinda93 commented 3 weeks ago

I had a look at this and it seems like the regex parsing was broken for the NuxtImg output.

I've pushed up a fix which is in v6.0.0-beta.4 of the sitmeap module, you can upgrade to it by deleting your lock file + node_modules and re-installing.

If you still have issues please use this as a reproduction https://stackblitz.com/edit/nuxt-starter-a5qk3s?file=app.vue, the codesandbox has issues running.

@harlan-zw

Thanks a lot for the response and quick fix. For some reason I am still facing the issue.

As per you suggestion I did the following in my project:

  1. Remove all the things: rm -Rf .output .nuxt node_modules package-lock.json.

  2. Update the version: "@nuxtjs/sitemap": "^6.0.0-beta.4",

  3. Ran the: npm install

  4. Run: npm run generate

  5. Observe the .output/public/__sitemap__/en.xml for all the images using automatic discovery.

For some reason I am still unable to get any images in my sitmap.xml file when using Nuxt Content and Nuxt Sitemap. I tried in my original project as well as on CodeSandBox. It did not work in both places.

As requested by you I tried on Stackblitz but for some reason unable to upload dummy images there and it suddenly breaks for some reason not sure why. I am facing some issues on Stackblitz.

I have updated code in both CodeSandBox and on Stackblitz.

Can you please have a look and let me know how to get the images in Sitemap.xml using the Automatic Image Discovery

Thanks a lot in advance.

Aravinda93 commented 3 weeks ago

@harlan-zw

Additionally, I tried the following:

  1. I added components/content/ProseImg.vue to force the images to be rendered as NuxtImg and passed the images in .md files as:
    ![Image1.](/img/Image1.png)

Then I ran the npm run generate even then I do not get the images in my Sitemap.xml file. I tried in my original project as well as in the CodeSandBox did not work on either of them.

I am getting the following contents in my sitemap.xml. I can see only the page-related things but not the images that I have added to my .md files.

I hope I am doing everything correctly, still, I do not get anything.

Aravinda93 commented 2 weeks ago

@harlan-zw

Just wanted to confirm if I can try something to fix the issue. Anything is required from my side for you to fix the issue?

Aravinda93 commented 2 weeks ago

@harlan-zw

Is there any alternative way or work-around to fix the issue for now until the final fix has been added to @nuxt/sitemap? Looking forward to some approach or fix.

harlan-zw commented 1 week ago

The issue seems to be quite simple, you have disabled ssr which means that when Nuxt prerenders the site, it won't prerender using the server. This means that none of the page content is available to the Sitemap module.

If you're using nuxt generate, there's no harm in having ssr enabled as it will always produce an output that doesn't rely on a server.

Saying that I did do some testing with your setup and noticed some duplicate loc and alternative entries which I've pushed up a fix for in the latest RC.

Aravinda93 commented 1 week ago

The issue seems to be quite simple, you have disabled ssr which means that when Nuxt prerenders the site, it won't prerender using the server. This means that none of the page content is available to the Sitemap module.

If you're using nuxt generate, there's no harm in having ssr enabled as it will always produce an output that doesn't rely on a server.

Saying that I did do some testing with your setup and noticed some duplicate loc and alternative entries which I've pushed up a fix for in the latest RC.

@harlan-zw

Thanks a lot its working fine now with ssr:true and able to get the images in sitemap.xml file. But I am facing one small issue:

I have a few tags in my .md files; if the tags have spaces, then the spaces are retained in the generated URL within the sitemap.xml file. Can you please let me know how to fix this?

I have a Nuxt content website with some of the markdown files in /content/index.md with tags such as:

  navigation:
  linkTitle: "Introduction"
  tags : ["Testing tools", "performance tests", "process automation", "supply chain management", "load tests"]

I am generating the sitemap.xml using the nuxtjs/sitemap with ssr:true during the generation of the sitemap it generates the URL with spaces such as:

 <url>
    <loc>http://localhost:3000/tags/performance tests</loc>
    <xhtml:link rel="alternate" href="http://localhost:3000/tags/performance tests" hreflang="x-default" />
    <xhtml:link rel="alternate" href="http://localhost:3000/tags/performance tests" hreflang="en" />
</url>

Since it generates the URL with spaces they are invalid but URLs are valid when I navigate to them then they are present with spaces:

http://localhost:3000/tags/performance%20tests

How to ensure the sitemap adds appropriate spaces and checks for valid URLs before generating the sitemap.xml using Nuxt Sitemap and replacing the spaces with URL-safe characters.