Skip to content

Allow customizing the way JSON-LD data is injected into pages#822

Merged
oscarotero merged 1 commit intolumeland:mainfrom
folliehiyuki:json-ld-custom
Feb 15, 2026
Merged

Allow customizing the way JSON-LD data is injected into pages#822
oscarotero merged 1 commit intolumeland:mainfrom
folliehiyuki:json-ld-custom

Conversation

@folliehiyuki
Copy link
Contributor

Description

The JSON-LD data can be placed inside a <script> tag anywhere on a HTML page. Google supports it either:

  • within <head> or <body> elements
  • injected into the document on first load via Javascript

Ref: https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data#supported-formats

Related Issues

Check List

  • Have you read the
    CODE OF CONDUCT
  • Have you read the document
    CONTRIBUTING
    • One pull request per feature. If you want to do more than one thing,
      send multiple pull request.
    • Write tests.
    • Run deno fmt to fix the code format before commit.
    • Document any change in the CHANGELOG.md.

@oscarotero
Copy link
Member

Why do you want to customize this?

@folliehiyuki
Copy link
Contributor Author

I prefer putting the data at the end of <body> instead of <head> to avoid cluttering the page's <head> section, even though it doesn't help much and isn't as SEO friendly. JSON-LD supports a lot of fields and can grow quite large, in my opinion.

I also think having the ability to inject the data into the page via Javascript is a nice addition. That's why I pass Page object into the function instead of its underlying document. Users can put this client-side script next to the page, for example.

@folliehiyuki
Copy link
Contributor Author

For the failing test, I don't know why my update affects the 2nd file's output.

@oscarotero
Copy link
Member

I see.
I would rather to make this more simple. Allowing a function is basically like running a processor that can do anything (not only customize the json-ld injection).
What do you think about a placement option? For example:

site.use(jsonLd({
  placement: "head" // The default option. Available options: "head" and "body"
});

@folliehiyuki
Copy link
Contributor Author

What do you think about adding a 3rd option false in addition to head and body? In that case the plugin simply exports jsonLdData string and we let the users decide what to do with it.

It's a bit weird for a user to write jsonLd to only get the exported jsonLdData string back, but the supported query syntax is pretty convenient.

@oscarotero
Copy link
Member

Ok, but in this case, I'd make this option a boolean:

  • true Place the JSON in the head (as it does now). It's the default value
  • false Updates the page.data.jsonLdData value with the final object, but without inserting it in the document (it omits this step)

This allows anyone to place it in a different position, or customize the object a bit more with a processor. In this case, a better option name could be insert or something similar.

site.use(jsonLd({
    insert: false
}));

site.process([".html"], (pages) => {
  for (const page of pages) {
    const { jsonLd } = page.data;
    const jsonLdContent = JSON.stringify(jsonLd);
  }
});

@folliehiyuki
Copy link
Contributor Author

I updated the PR with your suggestion.

This is unrelated, but too minor to be worth a GitHub issue: can you update markdown-it dependency to 14.1.1 in the next release. It fixed a perf regression (markdown-it/markdown-it@14.1.0...14.1.1).

@oscarotero oscarotero merged commit 5a530fc into lumeland:main Feb 15, 2026
6 checks passed
@oscarotero
Copy link
Member

Perfect, thanks!

can you update markdown-it dependency to 14.1.1 in the next release.

Sure, I have the deno task update-deps command to update all dependencies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants