Automatically creating The SEO Framework metadata for Bricks with Claude
Use Claude to automatically generate SEO Framework metadata from the content in Bricks text elements


We can use Claude with the Bricks extension to generate The SEO Framework metadata based on the content in Bricks text elements, all with a single Gato GraphQL query.
And with the Automation extension, we can automatically trigger the execution of this query when a new Bricks page is published.
This query uses Claude to analyze the content in Bricks text elements and generate The SEO Framework metadata (title and description) for better SEO.
We must provide the following variables:
customPostId
: The ID of the Bricks custom post to updateanthropicAPIKey
: The API key for the Anthropic API
You can customize the system message and prompt template to adjust how Claude generates the metadata.
Store the query as a new Persisted Query, with title "Create The SEO Framework metadata for Bricks with Claude"
, so we can use it in the Automation (see below).
Here is the GraphQL query:
query InitializeGlobalVariables
@configureWarningsOnExportingDuplicateVariable(enabled: false)
{
emptyArray: _echo(value: [])
@export(as: "elementTexts")
@remove
}
query GetBricksData($customPostId: ID!)
@depends(on: "InitializeGlobalVariables")
{
customPost(by:{ id: $customPostId }, status: any) {
id
title
bricksData(filterBy: { include: ["heading", "text"] })
@underEachArrayItem
@underJSONObjectProperty(by: { path: "settings.text" })
@export(as: "elementTexts")
}
}
query GenerateMetadataWithClaude(
$anthropicAPIKey: String!
$maxTokens: Int! = 32000
$promptTemplate: String! = """
You are an SEO expert specializing in metadata optimization.
I need to generate SEO metadata for a WordPress page using The SEO Framework plugin.
Based on the following content from the page, please generate:
1. A compelling SEO title (max 60 chars)
2. A meta description (max 160 chars)
Please respond in JSON format with this structure:
{
"title": "SEO title here",
"description": "Meta description here"
}
Return ONLY the JSON object. Do not include any explanations, markdown formatting, or code blocks. The response must be a valid JSON object starting with { and ending with }.
Content to analyze:
{$encodedContent}
"""
$model: String! = "claude-sonnet-4-0"
)
@depends(on: "GetBricksData")
{
encodedContent: _arrayJoin(
array: $elementTexts,
separator: "\n\n"
)
prompt: _strReplace(
search: "{$encodedContent}",
replaceWith: $__encodedContent,
in: $promptTemplate
)
claudeResponse: _sendJSONObjectItemHTTPRequest(input: {
url: "https://api.anthropic.com/v1/messages",
method: POST,
options: {
headers: [
{
name: "x-api-key",
value: $anthropicAPIKey
},
{
name: "anthropic-version",
value: "2023-06-01"
}
],
json: {
model: $model,
max_tokens: $maxTokens,
messages: [
{
role: "user",
content: $__prompt
}
],
}
}
})
@underJSONObjectProperty(by: { key: "content" })
@underArrayItem(index: 0)
@underJSONObjectProperty(by: { key: "text" })
@export(as: "jsonEncodedMetadata")
}
query ExtractMetadata
@depends(on: "GenerateMetadataWithClaude")
{
jsonEncodedMetadata: _echo(value: $jsonEncodedMetadata)
@remove
decodedMetadata: _strDecodeJSONObject(string: $jsonEncodedMetadata)
seoMetadataTitle: _objectProperty(
object: $__decodedMetadata,
by: { key: "title" }
)
@export(as: "seoMetadataTitle")
seoMetadataDescription: _objectProperty(
object: $__decodedMetadata,
by: { key: "description" }
)
@export(as: "seoMetadataDescription")
}
mutation UpdateSEOFrameworkMetadata($customPostId: ID!)
@depends(on: "ExtractMetadata")
{
updateCustomPost(
input: {
id: $customPostId
meta: {
_genesis_title: [$seoMetadataTitle],
_genesis_description: [$seoMetadataDescription],
_open_graph_title: [$seoMetadataTitle],
_open_graph_description: [$seoMetadataDescription],
_twitter_title: [$seoMetadataTitle],
_twitter_description: [$seoMetadataDescription],
}
}
) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
customPost {
id
metaTitle: metaValue(key: "_genesis_title")
metaDesc: metaValue(key: "_genesis_description")
socialTitle: metaValue(key: "_open_graph_title")
socialDesc: metaValue(key: "_open_graph_description")
twitterTitle: metaValue(key: "_twitter_title")
twitterDesc: metaValue(key: "_twitter_description")
}
}
}
The variables would look like this:
{
"customPostId": 123,
"anthropicAPIKey": "sk-ant-..."
}
Automation
To automatically trigger the execution of the query when a new Bricks page is published, create a new Automation rule with the following settings:
- Persisted Query:
"Create The SEO Framework metadata for Bricks with Claude"
(i.e. the one we created above) - Hook name:
gatographql:any_to_publish:page
- Dynamic GraphQL variables:
{
"customPostId": 1
}
