> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pastures.farm/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding Pages

> How to add new pages or tabs to the Pastures extension.

## Adding a Standalone Page

<Steps>
  <Step title="Create the Vue component">
    Add a new `.vue` file in `pkg/pastures/pages/`. Use the standard template:

    ```vue theme={null}
    <script setup lang="ts">
    import { ref, onMounted } from 'vue';
    import { engineFetch, isGlobalDemoMode, safeJson } from '../lib/pasturesApi';

    const loading = ref(true);
    const data = ref<any>(null);

    const DEMO_DATA = {
      items: [
        { id: '1', name: 'Example item', status: 'healthy' },
      ],
    };

    onMounted(async () => {
      if (isGlobalDemoMode()) {
        await new Promise((r) => setTimeout(r, 400));
        data.value = DEMO_DATA;
        loading.value = false;
        return;
      }

      const res = await engineFetch('/api/my-feature');
      data.value = safeJson(await res.json());
      loading.value = false;
    });
    </script>

    <template>
      <div class="pastures-page">
        <h1>My Feature</h1>
        <div v-if="loading" class="loading-indicator">Loading…</div>
        <div v-else>
          <!-- render data -->
        </div>
      </div>
    </template>
    ```
  </Step>

  <Step title="Register the route in index.ts">
    Import the component and add a route entry inside the `plugin()` function:

    ```typescript theme={null}
    import MyFeaturePage from './pages/MyFeaturePage.vue';

    plugin.addRoute({
      name:      'pastures-my-feature',
      path:      '/pastures/my-feature',
      component: MyFeaturePage,
      meta:      { product: 'pastures' },
    });
    ```
  </Step>

  <Step title="Add a virtualType in product.ts">
    Register the sidebar entry:

    ```typescript theme={null}
    virtualType({
      label:      'My Feature',
      name:       'pastures-my-feature',
      route:      { name: 'pastures-my-feature' },
      namespaced: false,
    });
    ```
  </Step>

  <Step title="Add to basicType array">
    Include the new type in the appropriate `basicType()` call so it appears in the sidebar section:

    ```typescript theme={null}
    basicType([
      // ... existing entries
      'pastures-my-feature',
    ]);
    ```
  </Step>

  <Step title="Set sidebar position with weightType">
    Control where the entry appears in the sidebar. Higher weight = higher position.

    ```typescript theme={null}
    weightType('pastures-my-feature', 50);
    ```
  </Step>

  <Step title="Add demo data">
    If your page calls `engineFetch`, add a path match in `lib/demoResponses.ts`:

    ```typescript theme={null}
    case '/api/my-feature':
      return {
        items: [
          { id: '1', name: 'Example item', status: 'healthy' },
        ],
      };
    ```

    If your page uses inline `fetch`, define a `DEMO_*` constant in the component and check `isGlobalDemoMode()` in `onMounted` (as shown in step 1).
  </Step>
</Steps>

***

## Adding a Tab to an Existing Tabbed Page

Tabbed container pages (`OperationsPage`, `HarvesterPage`, `InfrastructurePage`, `AIAgentsPage`) render child components as tabs.

<Steps>
  <Step title="Create the tab component">
    Create your `.vue` file in `pages/` as above, but add support for the `embedded` prop:

    ```vue theme={null}
    <script setup lang="ts">
    defineProps<{
      embedded?: boolean;
    }>();
    </script>

    <template>
      <div class="pastures-page">
        <h1 v-if="!embedded">My Tab Feature</h1>
        <!-- page content -->
      </div>
    </template>
    ```

    When `embedded` is `true`, the component hides its own header since the parent tabbed page provides the tab bar.
  </Step>

  <Step title="Import and add to the tabs array">
    In the parent tabbed page (e.g., `OperationsPage.vue`), import the new component and add it to the tabs configuration:

    ```typescript theme={null}
    import MyTabFeature from './MyTabFeaturePage.vue';

    const tabs = [
      // ... existing tabs
      { label: 'My Tab', component: MyTabFeature },
    ];
    ```
  </Step>

  <Step title="Add demo data">
    Follow the same demo data pattern described above for standalone pages.
  </Step>
</Steps>

<Info>
  You do **not** need to register a separate route or sidebar entry for tabs — the parent container page handles routing.
</Info>
