Skip to main content
StormyCMS

GraphQL Mutations

Mutations allow you to create, update, and delete content in your StormyCMS site. All mutations require authentication with your site API key and client ID.

Authentication

Don't forget to include your authentication headers in every request:

headers: {
'Content-Type': 'application/json',
'x-site-api-key': 'YOUR_SITE_API_KEY',
'x-client-id': 'YOUR_CLIENT_ID'
}

Page Mutations

Create a New Page

Create a new page with metadata and components.

mutation CreatePage(
$meta: MetadataInput!
$components: [ComponentInput!]!
$layoutId: ID!
$componentIds: [ID!]!
) {
create_page(
meta: $meta
components: $components
layout_id: $layoutId
component_ids: $componentIds
) {
id
meta {
title
description
keywords
}
layout_id
components {
id
name
text
}
}
}

Example:

const response = await fetch('https://api.stormycms.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-site-api-key': 'YOUR_SITE_API_KEY',
'x-client-id': 'YOUR_CLIENT_ID'
},
body: JSON.stringify({
query: `
mutation CreatePage($meta: MetadataInput!, $layoutId: ID!) {
create_page(
meta: $meta
components: []
layout_id: $layoutId
component_ids: []
) {
id
meta {
title
description
}
}
}
`,
variables: {
meta: {
title: "My New Page",
description: "A page created with the StormyCMS API",
keywords: ["cms", "api", "content"]
},
layoutId: "layout_123"
}
})
});

Update an Existing Page

Update a page's metadata, components, or layout.

mutation UpdatePage(
$id: ID!
$meta: MetadataInput!
$components: [ComponentInput!]!
$layoutId: ID!
$componentIds: [ID!]!
) {
update_page(
id: $id
meta: $meta
components: $components
layout_id: $layoutId
component_ids: $componentIds
) {
id
meta {
title
description
keywords
}
layout_id
updated_at
}
}

Example:

const response = await fetch('https://api.stormycms.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-site-api-key': 'YOUR_SITE_API_KEY',
'x-client-id': 'YOUR_CLIENT_ID'
},
body: JSON.stringify({
query: `
mutation UpdatePage($id: ID!, $meta: MetadataInput!) {
update_page(
id: $id
meta: $meta
components: []
layout_id: "layout_123"
component_ids: []
) {
id
meta {
title
description
}
}
}
`,
variables: {
id: "page_456",
meta: {
title: "Updated Page Title",
description: "This page has been updated",
keywords: ["updated", "content"]
}
}
})
});

Delete a Page

Permanently remove a page from your site.

mutation DeletePage($id: ID!) {
delete_page(id: $id) {
id
meta {
title
}
}
}

Example:

const response = await fetch('https://api.stormycms.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-site-api-key': 'YOUR_SITE_API_KEY',
'x-client-id': 'YOUR_CLIENT_ID'
},
body: JSON.stringify({
query: `
mutation DeletePage($id: ID!) {
delete_page(id: $id) {
id
meta {
title
}
}
}
`,
variables: {
id: "page_456"
}
})
});

Layout Mutations

Create a New Layout

Create a reusable layout for your pages.

mutation CreateLayout(
$name: String!
$components: [ComponentInput!]!
$componentIds: [ID!]!
) {
create_layout(
name: $name
components: $components
component_ids: $componentIds
) {
id
name
components {
id
name
}
created_at
}
}

Example:

const response = await fetch('https://api.stormycms.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-site-api-key': 'YOUR_SITE_API_KEY',
'x-client-id': 'YOUR_CLIENT_ID'
},
body: JSON.stringify({
query: `
mutation CreateLayout($name: String!) {
create_layout(
name: $name
components: []
component_ids: []
) {
id
name
}
}
`,
variables: {
name: "Blog Post Layout"
}
})
});

Update an Existing Layout

Modify a layout's structure or components.

mutation UpdateLayout(
$id: ID!
$name: String!
$components: [ComponentInput!]!
$componentIds: [ID!]!
) {
update_layout(
id: $id
name: $name
components: $components
component_ids: $componentIds
) {
id
name
updated_at
}
}

Delete a Layout

Remove a layout from your system.

mutation DeleteLayout($id: ID!) {
delete_layout(id: $id) {
id
name
}
}

Working with Components

Adding Components to a Page

When creating or updating a page, you can include components:

const components = [
{
name: "Header",
text: [
{
locale: "en",
value: "Welcome to My Page"
}
],
props: [
{
key: "className",
translations: [
{
locale: "en",
value: "page-header"
}
]
}
]
},
{
name: "TextBlock",
text: [
{
locale: "en",
value: "This is the main content of the page."
}
]
}
];

Nested Components

Components can have child relationships:

const containerComponent = {
name: "Container",
child_ids: ["child_1", "child_2"],
components: [
{
id: "child_1",
name: "Sidebar",
text: [{ locale: "en", value: "Sidebar content" }]
},
{
id: "child_2",
name: "MainContent",
text: [{ locale: "en", value: "Main content" }]
}
]
};

Error Handling

Always handle potential errors in your mutations:

async function executeMutation(query, variables) {
const response = await fetch('https://api.stormycms.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-site-api-key': 'YOUR_SITE_API_KEY',
'x-client-id': 'YOUR_CLIENT_ID'
},
body: JSON.stringify({ query, variables })
});
if (!response.ok) {
if (response.status === 401) {
throw new Error('Authentication failed: Check your API key and client ID');
} else if (response.status === 403) {
throw new Error('Permission denied: You may not have the required permissions');
} else if (response.status === 429) {
throw new Error('Rate limit exceeded: Try again later');
}
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
if (result.errors) {
const errorMessages = result.errors.map(err => err.message).join(', ');
throw new Error(`GraphQL errors: ${errorMessages}`);
}
return result.data;
}

Best Practices

  1. Validate input - Always validate data before sending mutations
  2. Handle errors gracefully - Provide clear error messages to users
  3. Use transactions - Group related mutations when possible
  4. Track changes - Keep a record of who made changes and when
  5. Backup data - Especially before bulk operations

Permissions

  • Site Admin - Can create, update, and delete pages
  • Site Editor - Can update existing pages (but not delete)
  • Site Contributor - Read-only access

Next Steps

Last updated: 2/27/26, 3:48 AM

StormyCMSPowerful Headless CMS with GraphQL API
Community
githubdiscordStormyCMS