Pular para o conteúdo
duxt

Hooks

O único hook de build que o duxt emite, o que ele entrega e por que existe apenas um.

O duxt emite um hook. É um hook de build do Nuxt, dispara uma vez por build e entrega todas as páginas do site como registos de pesquisa planos.

import { defineNuxtModule } from '@nuxt/kit';
import type { DuxtSearchRecord } from '@kirchdev/duxt/search-records';

export default defineNuxtModule({
  setup(_options, nuxt) {
    nuxt.hook('duxt:search:records', async (records) => {
      await upload(records);
    });
  }
});

Um exemplo completo — o esquema da coleção, o upsert, a remoção do que já não existe e a chave que nunca pode chegar a uma página — está em Envie suas páginas para o Typesense.

duxt:search:records

(records: readonly DuxtSearchRecord[]) => void | Promise<void>

Quando dispara. Depois de o Content ter analisado cada fonte, cada versão, cada idioma e cada secção gerada — incluindo os repositórios remotos que descarregou — e antes de o Nitro prerenderizar ou empacotar o que quer que seja. Um listener ainda pode escrever um ficheiro em public/ e vê-lo chegar à saída.

O que é um registo. Uma página, mais um por cada cabeçalho que ela tenha.

CampoTipoO que contém
idstringA identidade do registo, e uma chave primária válida em qualquer motor
urlstringOnde o leitor aterra — segmento de idioma e âncora incluídos
titlestringO cabeçalho que o registo cobre, ou o título da página no primeiro
contentstringAs palavras sob esse cabeçalho, sem marcação e com espaços normalizados
sourcestringDe que fonte veio, como segmentos de URL sem a versão
versionstringO rótulo da versão, onde a fonte tem versões — ausente onde não tem
localestringO idioma em que o conteúdo está escrito

id é um resumo hexadecimal em vez do URL, porque o Meilisearch só aceita A-Za-z0-9_- como identificador de documento. Deriva de url, por isso é igual em qualquer máquina e mantém-se enquanto a página ficar onde está — que é exatamente o que permite a um fornecedor fazer upsert em vez de reconstruir.

source é uma identidade, não um endereço: / para a documentação servida na raiz, /harbour para um segundo repositório, /harbour/api para uma secção gerada lá dentro. A versão fica deliberadamente de fora, para que uma faceta construída sobre source sobreviva a um lançamento e version, ao lado, seja o que restringe a uma só.

locale é o idioma do conteúdo, não o idioma de interface em que se está a ler. Um site com fontes não traduzidas obtém um conjunto de registos mesmo servindo sete idiomas — o mesmo parágrafo indexado sete vezes é uma resposta repetida.

O que ele deliberadamente não leva

  • Nenhum excerto. Um excerto é uma decisão sobre uma lista de resultados, e a lista de resultados é tua.
  • Nenhum nome de coleção. Isso é a contabilidade interna do índice do duxt, e um documento com essa chave parte no dia em que uma fonte ganha um idioma.
  • Nenhum rótulo de exibição. label, name e a legenda da versão são prosa para quem lê, traduzida por idioma. Um registo não é lido por ninguém.

O que fica fora do índice

Uma página que escreveu search: false não produz registo nenhum — a mesma exclusão que a caixa de pesquisa, a ferramenta MCP search_docs e ambos os índices llms já respeitam. O mesmo vale para uma fonte traduzida num idioma que duxt.locales não serve, porque indexá-la seria oferecer ao leitor um URL que devolve 404.

Onde um site serve duas regiões de um mesmo idioma sobre uma só árvore — pt-PT e pt-BR a ler a mesma pasta pt/ —, os registos endereçam a primeira. Os dois URL levam as mesmas palavras, por isso indexar ambos duplicaria o índice para dizer duas vezes o mesmo; um fornecedor que queira levar o leitor à sua própria região troca o segmento, o que o duxt não pode fazer porque não sabe quem está a pesquisar.

E quando ninguém está a ouvir, o duxt não constrói carga nenhuma: um site sem fornecedor não paga nada por o hook existir.

Por que existe apenas um

Uma extensão distribuível do duxt é uma camada Nuxt, não um objeto plugin:

export default defineNuxtConfig({
  extends: ['@kirchdev/duxt', 'duxt-typesense']
});

Isso já leva componentes, predefinições de app.config, coleções de content.config.ts, rotas de servidor, ferramentas MCP e um módulo próprio, num pacote com versão própria. Uma API duxt.plugins reimplementaria a resolução de camadas dentro de uma camada — e um registo onde um plugin escreve no momento do import bate na mesma parede que moldou sectionTypes: content.config.ts e o módulo do duxt são carregados por carregadores diferentes, por isso um registo mutável onde ambos escrevessem seriam dois registos. Um hook de build do Nuxt não tem esse problema, porque só a metade do módulo chega a vê-lo.

Por isso a superfície mantém-se pequena de propósito, e cada uma das outras entradas continua a ser a resposta certa à sua própria pergunta:

Queres mudarUsa
Uma cor, um tipo de letra, um espaçamentoUm token CSS — Sobrepor o tema
O que um componente desenhaSombreá-lo, ou um slot onde exista
O que o site diz sobre si próprioA chave duxt de app.config — Configuração
Um novo tipo de secção geradasectionTypes — Fontes
O que uma página desenha à sua voltaFrontmatter — Frontmatter
Onde o texto do site é indexadoEste hook
Esta página foi útil?