Criando um Mapa de Imagens para o Google

󰃭 28 Dec 2025 (updated: 28 Dec 2025 )

Eu fiz o meu novo Blog, esperei ele ser indexado pelo Google, só que percebi uma coisa: Pouquíssimas imagens haviam sido indexadas. Até que ao pesquisar, vi que faltava uma coisa importante: Um Mapa para o Google encontrar as imagens. E eu precisava resolver isso, já que é um site de artes.

E esse post é sobre como resolvi esse problema, e se você está enfrentando o mesmo problema, pode ser que isso também te ajude.

Encontrando uma Solução e Implementando

E ao buscar por como resolver isso, encontrei uma forma de resolver isso, e foi relativamente fácil fazer com que o Hugo gerasse mais um Sitemap além do sitemap.xml. Primeiro, tive que adicionar algumas linhas no hugo.yaml para poder fazer com que o Sitemap das imagens fosse gerado:

outputFormats:
  imagessitemap:
    baseName: imagessitemap
    mediaType: application/xml
    noUgly: true

Mas isso sozinho não faz muita coisa. Sendo assim, tive que adicionar mais uma linha em outro local no mesmo arquivo:

outputs:
  home:
    - html
    - json
    - rss
    - imagessitemap

Com isso, o Sitemap já estaria sendo gerado. Mas faltava o mais importante: O Leiaute que o Hugo usaria para gerar esse Sitemap. Com isso, eu encontrei duas alternativas.

Dariusz Więckiewicz

O do Dariusz Więckiewicz, foi a primeiro que testei e que implementei no meu Blog. E esse é o código do Dariusz:

{{- $pctx := . -}}
{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
{{- $pages := slice -}}
{{- if or $.IsHome $.IsSection -}}
{{- $pages = $pctx.RegularPages -}}
{{- else -}}
{{- $pages = $pctx.Pages -}}
{{- end -}}
{{- $limit := .Site.Config.Services.RSS.Limit -}}
{{- if ge $limit 1 -}}
{{- $pages = $pages | first $limit -}}
{{- end -}}

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">

{{ range where $pages "Sitemap.Disable" "ne" true }}
  {{ if or (.Params.featuredImage) (findRE `(?s)<img.+?>` .Content) }}
    {{- if .Permalink -}}
      <url>
        <loc>{{ .Permalink }}</loc>
        {{ if .Params.featuredImage }}

          {{- $ftimgsrc := "" -}}
          {{ if hasPrefix .Params.featuredImage "/" }}
              {{ $ftimgsrc = resources.Get .Params.featuredImage }}
          {{ else }}
              {{ if .Page.BundleType }}
                  {{ $ftimgsrc = .Page.Resources.GetMatch .Params.featuredImage }}
              {{ else }}
                  {{ $path := path.Join .Page.File.Dir .Params.featuredImage }}
                  {{ $ftimgsrc = resources.Get $path }}
              {{ end }}
          {{ end }}

          <image:image>
            <image:loc>{{ $ftimgsrc.Permalink }}</image:loc>
          </image:image>{{ end }}
          {{ if (findRE `(?s)<img.+?>` .Content) }}{{ range $k, $_ := findRE `(?s)<img.+?>` .Content }}{{ if $k }}{{ end }}
            <image:image>
              <image:loc>{{ replaceRE `(?s).*src="(.+?)".*` "$1" . | absURL }}</image:loc>
            </image:image>{{ end }}
        {{ end }}
      </url>{{- end -}}
  {{ end }}
{{ end }}
  
</urlset>

E esse Leiaute se mostrou efetivo: Ele pegou a imagem dos posts definida em .Params.Image no Front Matter de cada postagem, mas que falhou ao incluir as imagens das postagens no Mapa. E isso era um problema pra mim.

Leiaute feito por Dariusz Więckiewicz que seria muito bom, se as imagens dos posts estivessem com o endereço certo

Tudo porque, eu salvo as imagens de maneira que as imagens relativas a um post, eu guardo numa pasta images daquele post e as de uso compartilhado, eu salvo em /static/images, para estarem facilmente acessíveis ao escrever outros posts. Por exemplo, usando essa postagem de exemplo, a Imagem do Post estava definida como:

image: /images/desenhos/251227-romeo-alegre.webp

E podemos ver que isso deu muito certo com essa imagem, que está no endereço certo, que seria o http://localhost:1313/images/desenhos/251227-romeo-alegre.webp. Porém, não com as imagens dos posts, que ficaram como http://localhost:1313/images/251227-01.webp ao invés de http://localhost:1313/artes/251227-romeo-alegre/images/251227-01.webp, que seria o endereço correto. E eu queria muito que o Sitemap fosse gerado com tudo.

Hong Xu

E depois, procurei por outra solução, até que encontrei no Discourse do Hugo, uma pessoa chamada Hong Xu, que mostrou um outro Leiaute muito mais simples:

{{- $imageRegex := `.(avif|bmp|gif|jpeg|jpg|png|svg|svgz|webp)$` -}}

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">

  {{ range where .Site.Pages "Sitemap.Disable" "ne" true }}
    {{ $pagePermalink := .Permalink }}
    {{ $containsImage := false }}
    {{ range .Resources }}
      {{ if findRE $imageRegex .Permalink }}
        {{ if eq $containsImage false }}
          <url>
            <loc>{{ $pagePermalink }}</loc>
            {{ $containsImage = true }}
        {{ end }}
        <image:image>
          <image:loc>{{ .Permalink }}</image:loc>
        </image:image>
      {{ end }}
    {{ end }}
    {{ if eq $containsImage true }}
          </url>
    {{ end }}
  {{ end }}

</urlset>

E testei ele. E ele consegui incluir todas as imagens que estavam no corpo da postagem, mas não a que estava definida no .Params.Image do Front Matter.

Leiaute feito por Hong Xu. Seria muito bom se a imagem do Front Matter estivesse no Sitemap

Fazendo por mim mesmo

Como eu uso um modo um pouco diferente de colocar as imagens no Blog, os dois modelos não me satisfizeram completamente, pois eu salvo as imagens nas duas maneiras: Na própria pasta do post e na pasta /static/images.

Com isso, tive que implementar uma solução própria, modificando o código de Hong Xu e esse foi o código que implementei no Made by Romeo:

{{- $imageRegex := `.(avif|bmp|gif|jpeg|jpg|png|svg|svgz|webp)$` -}}

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
	<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">

{{ range where .Site.Pages "Sitemap.Disable" "ne" true }}
	{{ if .Params.Image }}
	<url>
		<loc>{{ .Permalink }}</loc>	
		<image:image>
			<image:loc>{{ .Params.Image | absURL }}</image:loc>
		</image:image> 
		{{ range .Resources }}
			{{ if findRE $imageRegex .Permalink }}
		<image:image>
			<image:loc>{{ .Permalink }}</image:loc>
        </image:image>
			{{ end }}
		{{ end }}
	</url>
	{{ end }}
{{ end }}
</urlset>

Tudo começa definindo quais seriam os formatos de arquivo que seriam buscados pelo site, com a variável imageRegex. Depois, o cabeçalho do XML é gerado com esse código:

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
	<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">

E com isso, vem a lógica, que é essa aqui:

{{ range where .Site.Pages "Sitemap.Disable" "ne" true }}
	{{ if .Params.Image }}
	<url>
		<loc>{{ .Permalink }}</loc>	
		<image:image>
			<image:loc>{{ .Params.Image | absURL }}</image:loc>
		</image:image> 
		{{ range .Resources }}
			{{ if findRE $imageRegex .Permalink }}
		<image:image>
			<image:loc>{{ .Permalink }}</image:loc>
        </image:image>
			{{ end }}
		{{ end }}
	</url>
	{{ end }}
{{ end }}

Tudo começa com o {{ range where .Site.Pages "Sitemap.Disable" "ne" true }} que apenas considera as páginas que estão habilitadas a entrar no Sitemap. E depois, vai para um {{ if .Params.Image }}, que verifica se aquela página tem uma imagem definida no Front Matter. Se não tiver, essa página será pulada e nada será adicionado.

E se tiver a imagem definida no Front Matter, o link permanente da postagem é colocado no Sitemap com um <loc>{{ .Permalink }}</loc> e a imagem do Front Matter também é adicionada, com esse bloco de comandos.

<image:image>
	<image:loc>{{ .Params.Image | absURL }}</image:loc>
</image:image> 

Basicamente, o parâmetro .Params.Image é tratado para que seja exibida a URL Absoluta. Ou seja, a URL que leva para aquela imagem. E depois disso, todas as imagens do post são adicionadas no Sitemap, com esse Bloco de comandos:

{{ range .Resources }}
	{{ if findRE $imageRegex .Permalink }}
		<image:image>
			<image:loc>{{ .Permalink }}</image:loc>
		</image:image>
	{{ end }}
{{ end }}

Aqui é usado o {{ range .Resources }} para exibir todos os recursos daquela página, e depois todos os arquivos são filtrados com o {{ if findRE $imageRegex .Permalink }} usando a variável $imageRegex, e as URLs que levam para essas imagens são incluídas no Sitemap. E esse foi o resultado:

Esse foi o resultado das minhas modificações. Finalmente funcionou do jeito que queria

Palavras Finais

Sinceramente estou gostando da experiência de usar o Hugo para os meus Blogs. O que me fez gostar mais dele é a possibilidade de fazer as coisas por mim mesmo, e isso é algo que eu adoro. E também, usar o Hugo me fez aprender mais sobre como um site é feito.

Não que eu não tenha aprendido nada com o WordPress, que é excelente, mas ter algo mais “cru” está me fazendo aprender mais, principalmente para implementar somente as coisas que eu quero.


Mais publicações como esta

Made by Romeo no ar!

󰃭 21 Dec 2025 (updated: 21 Dec 2025 ) | #hugo #made-by-romeo

Finalmente! Depois de alguns dias fazendo o meu mais novo Blog, ele está no ar com o nome de made by romeo e já publiquei alguns desenhos por lá!

Posso dizer que com os quase seis anos do Blog do Cantinho do Romeo, eu aprendi muita coisa, aprendizados que trouxe para o novo Blog. Porém, o Wordpress estava me limitando muito, além do Cantinho do Romeo parecer que ele se tornou “profissional demais”. Eu queria e precisava de algo mais despretensioso.

Até que encontrei o Hugo, que é o Gerador de Site Estático por trás deste blog que você está lendo. Aí vi que poderia ser mais despretensioso, sem a pressão de ser tão profissional assim. Com isso, me voltei a fazer um blog mais simples, e até com um pouco mais de personalidade.

Continuar a ler 