Documentation
Feedback
Guides
VTEX IO Apps

VTEX IO Apps
GraphQL API Complete Reference
vtex.rewriter
Version: 1.70.0
Latest version: 1.70.0

This document provides comprehensive GraphQL API documentation for the VTEX Rewriter application, covering architecture, schema, and practical usage examples.

📋 Table of Contents

🎯 API Overview

The Rewriter GraphQL API allows managing internal URLs and URL redirects for VTEX storefronts. Routes commonly have complex paths since they communicate with other systems and databases. The Rewriter app defines standard paths along with canonical (shorter) paths for better SEO.

Route Types

The Rewriter handles three main types of routes:

TypeDescription
InternalNavigation routes that can have complex standard paths and canonical paths for improved SEO. Include product, search, and navigation routes.
RedirectRoutes that redirect one path to another for URL changes, content removal, SEO improvements, etc.

Main Functionalities

  • Create and manage internal routes
  • Create canonical paths for internal routes
  • Create and manage redirect routes
  • Delete routes and canonical paths
  • Support for multi-binding (multi-tenant) scenarios

🏗️ GraphQL Architecture

API Interaction Flow

📜 Schema Overview

Main Schema


_10
type Query {
_10
redirect: QueryRedirect!
_10
internal: QueryInternal!
_10
}
_10
_10
type Mutation {
_10
redirect: MutateRedirect!
_10
internal: MutateInternal!
_10
}

Query Type

FieldTypeDescription
redirectQueryRedirect!Provides redirect routes data for managing path redirections
internalQueryInternal!Provides internal routes data for navigation routes

Mutation Type

FieldTypeDescription
redirectMutateRedirect!Updates or deletes redirect routes
internalMutateInternal!Updates or deletes internal routes

🔍 Query Operations

QueryRedirect

FieldArgumentTypeDescription
getRedirectReturns a specific redirect route
pathString!Path of the route to fetch
locatorRouteLocatorObject with store locale and route origin info
listRedirectsListRedirectsResponse!Lists all redirect routes with pagination
limitIntNumber of results per page
nextStringPagination token for next page

QueryInternal

FieldArgumentTypeDescription
getInternalReturns a specific internal route
pathString!Path of the route to fetch
locatorRouteLocatorObject with store locale and route origin info
listInternalsListInternalsResponse!Lists all internal routes with pagination
limitIntNumber of results per page
nextStringPagination token for next page
routes[RoutesByBinding!]Lists routes by entity type and binding
locatorEntityLocatorObject with entity type information

✏️ Mutation Operations

MutateRedirect

FieldArgumentTypeDescription
saveRedirect!Creates or updates a redirect route
routeRedirectInput!Redirect route data
saveManyBoolean!Creates/updates multiple redirects
routes[RedirectInput!]!Array of redirect routes
deleteBoolean!Deletes a redirect route
pathString!Path to delete
locatorRouteLocatorRoute locator info

MutateInternal

FieldArgumentTypeDescription
saveInternal!Creates or updates an internal route
routeInternalInput!Internal route data
saveManyBoolean!Creates/updates multiple internal routes
routes[InternalInput!]!Array of internal routes
disableRedirectBooleanDisable automatic redirects
deleteBoolean!Deletes an internal route
pathString!Path to delete
locatorRouteLocatorRoute locator info

📊 Data Types Reference

Core Types

Redirect


_10
type Redirect {
_10
from: String! # Source URL path
_10
to: String! # Destination URL path
_10
type: RedirectTypes! # PERMANENT (301) or TEMPORARY (302)
_10
binding: String! # Binding ID for multi-tenant
_10
endDate: String # Expiration date (ISO format)
_10
origin: String # Origin/source of creation
_10
}

Internal


_12
type Internal {
_12
from: String! # URL pattern/path
_12
type: String! # Route type (product, category, etc.)
_12
id: String! # Entity ID
_12
declarer: String! # App that declared the route
_12
binding: String! # Binding ID
_12
query: JSON # Additional query parameters
_12
endDate: String # Expiration date
_12
alternates: [Alternates] # Alternative routes per binding
_12
disableSitemapEntry: Boolean # Exclude from sitemap
_12
resolveAs: String # How to resolve the route
_12
}

Input Types

RouteLocator


_10
input RouteLocator {
_10
from: String! # Route path
_10
binding: String # Binding identifier
_10
}

EntityLocator


_10
input EntityLocator {
_10
id: String! # Entity identifier
_10
type: String! # Entity type
_10
}

RedirectInput


_10
input RedirectInput {
_10
from: String!
_10
to: String!
_10
type: RedirectTypes!
_10
binding: String!
_10
endDate: String
_10
}

InternalInput


_11
input InternalInput {
_11
from: String!
_11
type: String!
_11
id: String!
_11
declarer: String!
_11
binding: String!
_11
query: JSON
_11
endDate: String
_11
disableSitemapEntry: Boolean
_11
resolveAs: String
_11
}

Response Types

RoutesByBinding


_10
type RoutesByBinding {
_10
binding: String! # Binding identifier
_10
route: String! # Route path
_10
}

ListRedirectsResponse


_10
type ListRedirectsResponse {
_10
routes: [Redirect!]! # Array of redirect routes
_10
next: String # Pagination token
_10
}

ListInternalsResponse


_10
type ListInternalsResponse {
_10
routes: [Internal!]! # Array of internal routes
_10
next: String # Pagination token
_10
}

💡 Usage Examples

Query Examples

Get Specific Redirect


_11
query GetRedirect($path: String!, $binding: String!) {
_11
redirect {
_11
get(path: $path, locator: { from: $path, binding: $binding }) {
_11
from
_11
to
_11
type
_11
binding
_11
endDate
_11
}
_11
}
_11
}

Variables:


_10
{
_10
"path": "/old-product-url",
_10
"binding": "my-store-binding"
_10
}

List Redirects (Paginated)


_13
query ListRedirects($limit: Int, $next: String) {
_13
redirect {
_13
listRedirects(limit: $limit, next: $next) {
_13
routes {
_13
from
_13
to
_13
type
_13
binding
_13
}
_13
next
_13
}
_13
}
_13
}

Get Internal Route


_15
query GetInternalRoute($path: String!, $binding: String!) {
_15
internal {
_15
get(path: $path, locator: { from: $path, binding: $binding }) {
_15
from
_15
type
_15
id
_15
declarer
_15
binding
_15
alternates {
_15
binding
_15
route
_15
}
_15
}
_15
}
_15
}

Get Routes by Entity


_10
query GetRoutesByEntity($id: String!, $type: String!) {
_10
internal {
_10
routes(locator: { id: $id, type: $type }) {
_10
binding
_10
route
_10
}
_10
}
_10
}

Mutation Examples

Create Permanent Redirect


_10
mutation CreateRedirect($route: RedirectInput!) {
_10
redirect {
_10
save(route: $route) {
_10
from
_10
to
_10
type
_10
binding
_10
}
_10
}
_10
}

Variables:


_10
{
_10
"route": {
_10
"from": "/old-path",
_10
"to": "/new-path",
_10
"type": "PERMANENT",
_10
"binding": "my-store",
_10
"endDate": "2025-12-31T23:59:59.999Z"
_10
}
_10
}

Create Internal Route


_11
mutation CreateInternalRoute($route: InternalInput!) {
_11
internal {
_11
save(route: $route) {
_11
from
_11
type
_11
id
_11
declarer
_11
binding
_11
}
_11
}
_11
}

Variables:


_10
{
_10
"route": {
_10
"from": "/custom-page",
_10
"type": "userRoute",
_10
"id": "custom-page-1",
_10
"declarer": "my-app",
_10
"binding": "my-store"
_10
}
_10
}

Bulk Create Redirects


_10
mutation CreateMultipleRedirects($routes: [RedirectInput!]!) {
_10
redirect {
_10
saveMany(routes: $routes)
_10
}
_10
}

Variables:


_16
{
_16
"routes": [
_16
{
_16
"from": "/old-1",
_16
"to": "/new-1",
_16
"type": "PERMANENT",
_16
"binding": "my-store"
_16
},
_16
{
_16
"from": "/old-2",
_16
"to": "/new-2",
_16
"type": "TEMPORARY",
_16
"binding": "my-store"
_16
}
_16
]
_16
}

Delete Route


_10
mutation DeleteRedirect($path: String!, $binding: String!) {
_10
redirect {
_10
delete(path: $path, locator: { from: $path, binding: $binding })
_10
}
_10
}

🏷️ Custom Directives

The Rewriter uses three custom GraphQL directives for enhanced functionality:

@initialize

Sets up request context and initializes resources needed for the operation.

@ensureAuthorization

Enforces admin access requirements for administrative operations.

@withAuthMetrics

Tracks authorization and access metrics for monitoring and analytics.


For error handling patterns, see Error Handling.
For performance monitoring, see Cache & Performance.
For multi-binding scenarios, see Multi-binding & Canonicals.

See also
Vtex.rewriter
VTEX IO Apps
VTEX App Store
VTEX IO Apps
Was this helpful?