# GraphQL fragments
fragment CountryBasicInfo on Country {
  code
  name
}

query GetCountryDetails {
  country(code: "US") {
    ...CountryBasicInfo # Spread fragment fields
    capital # Add extra fields
  }
}
```

**Fragment masking** takes this further by ensuring components can only access the data they explicitly request—pioneered by **Relay** and now enhanced in **Apollo Client 3.12**.

## Step 1: Enable Fragment Masking

Ensure your `codegen.ts` uses the client preset (from Part 2):

```typescript
const config: CodegenConfig = {
  overwrite: true,
  schema: "https://countries.trevorblades.com/graphql",
  documents: ["src/**/*.vue", "src/**/*.graphql"],
  generates: {
    "src/gql/": {
      preset: "client",
      plugins: [],
      config: { useTypeImports: true },
    },
  },
};
```

This generates:

- `FragmentType<T>`: Masked fragment types for props
- `useFragment()`: Function to unmask fragment data
- Type safety to prevent accessing non-fragment fields

## Step 2: Your First Fragment with Masking

Let's create a `CountryCard` component that declares its own data requirements:

```vue
<script setup lang="ts">
// Define what data this component needs
const CountryCard_CountryFragment = graphql(`
  fragment CountryCard_CountryFragment on Country {
    code
    name
    emoji
    capital
    phone
    currency
  }
`);

// Props accept a masked fragment type
interface Props {
  country: FragmentType<typeof CountryCard_CountryFragment>;
}

const props = defineProps<Props>();

// Unmask to access the actual data (reactive for Vue)
const country = computed(() =>
  useFragment(CountryCard_CountryFragment, props.country)
);
</script>

<template>
  <div class="country-card">
    <h3>{{ country.emoji }} {{ country.name }}</h3>
    <p>Capital: {{ country.capital }}</p>
    <p>Phone: +{{ country.phone }}</p>
    <p>Currency: {{ country.currency }}</p>
  </div>
</template>
```

## Understanding Fragment Masking: The Key to Data Isolation

**Fragment masking** is the core concept that makes this pattern so powerful. It's not just about code organization—it's about **data access control and encapsulation**.

### What Fragment Masking Actually Does

Think of fragment masking like **access control in programming languages**. Just as a module can have private and public methods, fragment masking controls which components can access which pieces of data.

```typescript
// Without fragment masking (traditional approach)
const result = useQuery(GET_COUNTRIES);
const countries = result.value?.countries || [];

// ❌ Parent can access ANY field from the query
console.log(countries[0].name); // Works
console.log(countries[0].capital); // Works
console.log(countries[0].currency); // Works
```

With fragment masking enabled:

```typescript
// ✅ Parent component CANNOT access fragment fields
const name = result.value?.countries[0].name; // TypeScript error!

// ✅ Only CountryCard can access its fragment data
const country = useFragment(CountryCard_CountryFragment, props.country);
console.log(country.name); // Works!
```

### The Power of Data Encapsulation

Fragment masking provides **true data encapsulation**:

1. **Prevents Implicit Dependencies**: Parent components can't accidentally rely on data their children need
2. **Catches Breaking Changes Early**: If a child component removes a field, the parent can't access it anymore
3. **Enforces Component Boundaries**: Each component owns its data requirements
4. **Enables Safe Refactoring**: Change a fragment without breaking unrelated components

### Why This Matters

Without fragment masking, parent components can accidentally depend on child fragment data. When the child removes a field, the parent breaks at runtime. With fragment masking, TypeScript catches this at compile time.

```typescript
// Parent can only access explicitly requested fields
countries[0].id; // ✅ Works (parent requested this)
countries[0].name; // ❌ TypeScript error (only in fragment)

// Child components unmask their fragment data
const country = useFragment(CountryCard_CountryFragment, props.country);
country.name; // ✅ Works (component owns this fragment)
```

> **📝 Vue Reactivity Note**: Always wrap `useFragment` in a `computed()` for Vue reactivity. This ensures the component updates when fragment data changes.

## Step 3: Parent Component Uses the Fragment

Now the parent component includes the child's fragment in its query:

```vue
<script setup lang="ts">
const COUNTRIES_WITH_DETAILS_QUERY = graphql(`
  query CountriesWithDetails {
    countries {
      code
      # Parent can add its own fields
      region
      # Child component's fragment
      ...CountryCard_CountryFragment
    }
  }
`);

const { result, loading, error } = useQuery(COUNTRIES_WITH_DETAILS_QUERY);

// Parent can access its own fields
const countriesByRegion = computed(() => {
  if (!result.value?.countries) return {};

  return result.value.countries.reduce(
    (acc, country) => {
      const region = country.region;
      if (!acc[region]) acc[region] = [];
      acc[region].push(country);
      return acc;
    },
    {} as Record<string, typeof result.value.countries>
  );
});

// But parent CANNOT access fragment fields:
// const name = result.value?.countries[0].name ❌ TypeScript error!
</script>

<template>
  <div class="countries-container">
    <div v-if="loading">Loading countries...</div>
    <div v-else-if="error">Error: {{ error.message }}</div>
    <div v-else class="countries-by-region">
      <div
        v-for="(countries, region) in countriesByRegion"
        :key="region"
        class="region-section"
      >
        <h2>{{ region }}</h2>
        <div class="country-grid">
          <CountryCard
            v-for="country in countries"
            :key="country.code"
            :country="country"
          />
        </div>
      </div>
    </div>
  </div>
</template>
```

## The Magic of Fragment Masking

Here's what just happened:

```mermaid
graph TB
    subgraph "GraphQL Query Result"
        QR["countries: Country[]"]
    end

    subgraph "Parent Component"
        PC["Parent can access:<br/>• countries[].code<br/>• countries[].region<br/>❌ countries[].name"]
    end

    subgraph "Child Component"
        CC["CountryCard receives:<br/>Masked Fragment Data"]
        UF["useFragment() unmasks:<br/>• code<br/>• name<br/>• emoji<br/>• capital"]
    end

    QR --> PC
    QR --> CC
    CC --> UF
```

The parent component **cannot access** fields from `CountryCard_Fragment`—they're masked! Only `CountryCard` can unmask and use that data.

## Step 4: Nested Fragments

Fragments can include other fragments, creating a hierarchy:

```graphql