npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gatsby-plugin-ai-pages

v1.0.8

Published

Generates AI-readable .md pages and llms.txt for Gatsby + WordPress projects

Downloads

769

Readme

gatsby-plugin-ai-pages

Generates AI-readable .md pages and llms.txt for Gatsby + WordPress (headless CMS) projects.

Every WordPress post gets a clean Markdown version at /{lang}/{path}/{slug}.md. A combined site index is generated at /llms.txt. Files are written as raw static files — no HTML wrapper, no JavaScript bundle — so AI agents and LLM crawlers receive pure text instantly.


Install

npm install gatsby-plugin-ai-pages

Requirements

  • Gatsby v4 or v5
  • gatsby-source-wordpress configured and connected to WordPress
  • WPGraphQL plugin active on your WordPress site

Usage

Single language

// gatsby-config.js
module.exports = {
  siteMetadata: {
    title: "My Site",
    description: "My site description",
    siteUrl: "https://your-site.com",
  },
  plugins: [
    // ... your existing plugins

    {
      resolve: "gatsby-plugin-ai-pages",
      options: {
        postTypes: [
          { graphqlType: "allWpPost", urlPath: "blog", label: "Blog Posts" },
        ],
      },
    },
  ],
};

Produces:

/blog/{slug}.md
/llms.txt

Multiple post types

{
  resolve: "gatsby-plugin-ai-pages",
  options: {
    postTypes: [
      { graphqlType: "allWpPost",      urlPath: "blog",        label: "Blog Posts" },
      { graphqlType: "allWpProject",   urlPath: "projects",    label: "Projects" },
      { graphqlType: "allWpCaseStudy", urlPath: "case-studies",label: "Case Studies" },
      { graphqlType: "allWpEvent",     urlPath: "events",      label: "Events" },
    ],
  },
}

Multilingual sites (WPML)

For path-based multilingual sites (/en/blog/slug, /ar/blog/slug), pass a langMapping object that maps WordPress locale IDs to URL prefixes. This matches how WPML exposes language per post via the locale.id field.

{
  resolve: "gatsby-plugin-ai-pages",
  options: {
    langMapping: {
      "en_US":  "en",
      "ar":     "ar",
      "zh_CN":  "zh-hans",
      "tr_TR":  "tr",
    },
    postTypes: [
      { graphqlType: "allWpPost",      urlPath: "blog",       label: "Blog Posts" },
      { graphqlType: "allWpNews",      urlPath: "news",       label: "News" },
      { graphqlType: "allWpInsight",   urlPath: "insights",   label: "Insights" },
    ],
  },
}

Produces:

/en/blog/{slug}.md
/ar/blog/{slug}.md
/zh-hans/blog/{slug}.md
/llms.txt              ← combined index, grouped by language and post type

The plugin fetches all posts in a single GraphQL query per post type, reads locale.id from each post, and routes each post to the correct language folder automatically.


Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | postTypes | array | [{ graphqlType: "allWpPost", urlPath: "blog", label: "Blog Posts" }] | Post types to generate .md pages for | | postTypes[].graphqlType | string | — | GraphQL query name for this post type, e.g. allWpProject | | postTypes[].urlPath | string | — | URL prefix, e.g. projects/projects/{slug}.md | | postTypes[].label | string | urlPath | Section heading used in /llms.txt | | langMapping | object | null | Maps WPML locale IDs to URL prefixes. Omit for single-language sites. | | siteUrl | string | siteMetadata.siteUrl | Override the site URL used to build links in frontmatter. |


What gets generated

/{lang}/{path}/{slug}.md

---
title: "Your Post Title"
description: "Excerpt up to 200 characters"
date: "2024-06-01T10:00:00"
slug: "your-post-slug"
lang: "en"
url: "https://your-site.com/en/blog/your-post-slug"
canonical: "https://your-site.com/en/blog/your-post-slug"
image: "https://your-wp.com/wp-content/uploads/hero.jpg"
author: "Author Name"
categories: ["Tech"]
tags: ["gatsby", "wordpress"]
---

## Post heading

Full post body converted from WordPress HTML to clean Markdown...

/llms.txt

# My Site

> My site description

# Language: EN

## Blog Posts

- [Post Title](https://your-site.com/en/blog/post-slug)
  Short excerpt...
  Markdown: https://your-site.com/en/blog/post-slug.md

# Language: AR

## Blog Posts

- [Post Title in Arabic](https://your-site.com/ar/blog/post-slug)
  Short excerpt...
  Markdown: https://your-site.com/ar/blog/post-slug.md

---
Generated: 2026-07-06

Home page

The home page (WordPress slug home) is automatically written as index.md per language:

/en/index.md
/ar/index.md
/zh-hans/index.md

No extra config needed — this happens automatically when allWpPage is included in postTypes.


AWS Amplify

customHttp.yml is not required. Amplify automatically serves .md and llms.txt files with the correct content type when they exist as raw static files in /public.

If you want to explicitly enforce Content-Type: text/markdown in the response headers (for strict AI agent compatibility), add customHttp.yml to your project root:

# customHttp.yml — optional
customHeaders:
  - pattern: "*.md"
    headers:
      - key: Content-Type
        value: "text/markdown; charset=utf-8"

  - pattern: "/llms.txt"
    headers:
      - key: Content-Type
        value: "text/plain; charset=utf-8"

How it works

The plugin uses Gatsby's onPostBuild hook — after Gatsby finishes building all pages, it writes raw .md and llms.txt files directly to /public. Amplify deploys the entire /public folder to the CDN, so the files are served as plain static text with no HTML wrapper and no JavaScript.

gatsby build
  → Gatsby builds all pages into /public
  → onPostBuild runs
  → plugin writes /public/en/blog/slug.md  (raw text)
  → plugin writes /public/llms.txt
  → Amplify deploys /public to CDN
  → AI agents fetch /en/blog/slug.md → instant plain text response

Finding GraphQL type names

Custom post types in WordPress must be registered with WPGraphQL (show_in_graphql: true). The Gatsby GraphQL type name follows the pattern all + Wp + PascalCase post type name.

To find the exact name for your project, run this in GraphiQL (http://localhost:8000/___graphql):

{
  __schema {
    queryType {
      fields {
        name
      }
    }
  }
}

Look for fields starting with allWp.

| WordPress post type | GraphQL type name | |---|---| | Posts (default) | allWpPost | | Custom: news | allWpNews | | Custom: case_study | allWpCaseStudy | | Custom: our_people | allWpOurpeople |


Testing locally

gatsby build && gatsby serve
curl http://localhost:9001/en/blog/your-post-slug.md
curl http://localhost:9001/llms.txt

License

MIT