Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Working With Data
  2. Graphql Colocation

GraphQL Colocation

Organizing GraphQL files with components using near-operation-file pattern

Now that you know how to write GraphQL operations, let's discuss where to organize them. Colocation keeps your GraphQL files next to the components that use them, improving discoverability and maintainability.

What Colocation Means

In our GraphQL setup, "colocation" refers to the near-operation-file preset pattern where:

  • .graphql files are placed in the same folder as the components that use them
  • Generated TypeScript files (.graphql.ts) are created alongside the .graphql files
  • This is NOT about embedding GraphQL strings directly in component files

This approach, documented in the Guild's near-operation-file guide, provides the best balance of organization and type safety.

Directory Structure

Component-Level Operations

For operations specific to a single component:

Benefits of This Approach

  1. Discoverability: GraphQL operations are right next to the components using them
  2. Maintainability: Easy to update operations when modifying components
  3. Type Safety: Generated types are imported from the same directory
  4. Modularity: Components are self-contained with their data requirements
  5. Refactoring: Moving components automatically moves their GraphQL files

Before and After Examples

❌ Don't do this - Centralized Operations

Old Pattern: All operations in a central location

Problems:

  • Operations disconnected from components
  • Hard to find what queries a component uses
  • Refactoring requires hunting down imports
  • No clear ownership of operations
  • Leads to bloated operations files that request too much data and query too many levels deep.
  • Types become difficult to reason about and maintain.

✅ Do this - Colocated Operations

New Pattern: Operations next to components

Benefits:

  • Clear ownership and organization
  • Easy to see component's data needs
  • Self-contained components
  • Natural code splitting
  • Types are scoped to the component and are easy to reason about

How Generated Files Work

When codegen runs (automatically during turbo run dev or manually with turbo run codegen), the near-operation-file preset:

  1. Finds all .graphql files in your app
  2. Generates a .graphql.ts file next to each one
  3. Includes typed document nodes and operation types

Example Generated Output

For this operation:

Generates this TypeScript file:

Important: NOT Inline GraphQL

❌ Don't do this - Inline GraphQL Strings

✅ Do this - Separate .graphql Files

Organizing Complex Components

For components with multiple operations:

Best Practices

✅ Do

  • Place .graphql files in the same folder as components
  • Use descriptive names for operation files
  • Group related operations in the same file
  • Keep fragments scoped to a single component whenever possible

❌ Don't

  • Put GraphQL strings directly in component files
  • Create deeply nested GraphQL folders
  • Share component-specific operations
  • Manually edit generated .graphql.ts files
  • Import the same fragment directly into multiple unrelated components: instead, use fragment composition: spread a child fragment into a parent fragment and pass typed data down via props

Cross-Feature Contracts

There are two different ways a fragment can appear in multiple places, and only one is an anti-pattern:

  • Composition (✅ correct): A child fragment (e.g., ChatroomChatbotsData) is spread via ...ChatroomChatbotsData into a parent fragment (LiveChatroomData). The parent query fetches all data in one request, and typed props flow downward to each child component. This is the recommended approach for decomposing large fragments: it does not violate the "don't share fragments" guideline.
  • Direct sharing (❌ avoid): The same fragment document is imported by two unrelated leaf components that each make their own useQuery call using that fragment's fields. This creates duplicate queries and breaks the single-query-at-the-top pattern.

If a fragment is genuinely needed in multiple unrelated contexts, consider whether a shared parent component should own the query, or whether the relevant components can be restructured so data flows downward via props.

Next, we'll learn about fragments, which help optimize and reuse field selections across your operations.

Previous

Working with data / GraphQL Operations

Next

Working with data / GraphQL Fragments

On this page

What Colocation Means
Directory Structure
Component-Level Operations
Benefits of This Approach
Before and After Examples
❌ Don't do this - Centralized Operations
✅ Do this - Colocated Operations
How Generated Files Work
Example Generated Output
Important: NOT Inline GraphQL
❌ Don't do this - Inline GraphQL Strings
✅ Do this - Separate .graphql Files
Organizing Complex Components
Best Practices
✅ Do
❌ Don't
Cross-Feature Contracts