# Developer use cases for project map

> This section provides information on how to use project maps for common scenarios.

Source: https://docs.uniform.app/docs/guides/project-maps/developer-use-cases

Learn actions you can take to work with [project maps](../project-maps).

## Get a composition from project map

Use [`CanvasClient.getCompositionByNodePath`](https://docs.uniform.app/docs/sdk/canvas-client#fetching-a-single-composition) to fetch the composition attached to a project map node by its path (there are some [exceptions](https://docs.uniform.app/docs/guides/composition/url-management/routing#dynamic-routes)):

```typescript
import { CanvasClient, CANVAS_PUBLISHED_STATE } from "@uniformdev/canvas";

const canvasClient = new CanvasClient({
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

const { composition } = await canvasClient.getCompositionByNodePath({
  projectMapNodePath: "/company/about-us",
  state: CANVAS_PUBLISHED_STATE,
});
```

In a Nuxt app, use `useUniformComposition` in a [catch-all route](https://nuxt.com/docs/guide/directory-structure/pages#catch-all-route) to render all pages in a single place:

`/pages/[...path].vue`

```html
<script lang="ts" setup>
const route = useRoute();
const path = route.params.path;
const pathString = Array.isArray(path) ? path.join("/") : path;

const { composition } = await useUniformComposition({
  projectMapNodePath: pathString ? `/${pathString}` : "/"
});
</script>
```

See the [Canvas Client SDK](https://docs.uniform.app/docs/sdk/canvas-client) for initialization options (including EU region hosts), draft/published states, and the full method reference.

## Get all compositions from project map

_For the US region:_

**Next.js**

An example to define the paths of the compositions to be static-generated:

`/pages/[[...path]].tsx`

```typescript
import { ProjectMapClient } from "@uniformdev/project-map";
import { GetStaticPaths } from "next";

const projectMapClient = new ProjectMapClient({
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

export const getStaticPaths: GetStaticPaths = async () => {
  const { nodes } = await projectMapClient.getNodes({
    projectMapId: "[!!! UNIFORM PROJECT MAP ID !!!]",
  });

  return {
    paths:
      nodes?.filter((node) => node.compositionId).map((node) => node.path) ??
      [],
    fallback: false,
  };
};
```

**Nuxt**

An example to fetch the compositions to show in a navigation component.
The [useAsyncData](https://nuxt.com/docs/api/composables/use-async-data) is needed to make sure this data fetching is only made once on the server, without re-fetching on the client.

`/pages/pageWithNavigation.vue`

```html
<script lang="ts" setup>
import { CANVAS_DRAFT_STATE, CANVAS_PUBLISHED_STATE } from "@uniformdev/canvas";

const { $preview: preview } = useNuxtApp();
const uniformConfig = useRuntimeConfig().public.$uniform;

const { data: navigationItems } = useAsyncData(
  `project-map-nodes-${preview}`,
  async () => {
    const projectMapClient = new ProjectMapClient({
      apiKey: uniformConfig.readOnlyApiKey,
      projectId: uniformConfig.projectId,
    });

    const { nodes } = await projectMapClient.getNodes({
      depth: 1,
      state: process.env.NODE_ENV === "development" || preview
        ? CANVAS_DRAFT_STATE
        : CANVAS_PUBLISHED_STATE,
    });

    return nodes
      ?.filter((node) => node.compositionId)
      .map((node) => ({
        title: node.name,
        url: node.path,
      })) ?? [];
  }
);
</script>
```

_For the EU region:_

**Next.js**

An example to define the paths of the compositions to be static-generated:

`/pages/[[...path]].tsx`

```typescript
import { ProjectMapClient } from "@uniformdev/project-map";
import { GetStaticPaths } from "next";

const projectMapClient = new ProjectMapClient({
  apiHost: 'https://eu.uniform.app',
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

export const getStaticPaths: GetStaticPaths = async () => {
  const { nodes } = await projectMapClient.getNodes({
    projectMapId: "[!!! UNIFORM PROJECT MAP ID !!!]",
  });

  return {
    paths:
      nodes?.filter((node) => node.compositionId).map((node) => node.path) ??
      [],
    fallback: false,
  };
};
```

**Nuxt**

An example to fetch the compositions to show in a navigation component.
The [useAsyncData](https://nuxt.com/docs/api/composables/use-async-data) is needed to make sure this data fetching is only made once on the server, without re-fetching on the client.

`/pages/pageWithNavigation.vue`

```html
<script lang="ts" setup>
import { CANVAS_DRAFT_STATE, CANVAS_PUBLISHED_STATE } from "@uniformdev/canvas";

const { $preview: preview } = useNuxtApp();
const uniformConfig = useRuntimeConfig().public.$uniform;

const { data: navigationItems } = useAsyncData(
  `project-map-nodes-${preview}`,
  async () => {
    const projectMapClient = new ProjectMapClient({
      apiHost: 'https://eu.uniform.app',
      apiKey: uniformConfig.readOnlyApiKey,
      projectId: uniformConfig.projectId,
    });

    const { nodes } = await projectMapClient.getNodes({
      depth: 1,
      state: process.env.NODE_ENV === "development" || preview
        ? CANVAS_DRAFT_STATE
        : CANVAS_PUBLISHED_STATE,
    });

    return nodes
      ?.filter((node) => node.compositionId)
      .map((node) => ({
        title: node.name,
        url: node.path,
      })) ?? [];
  }
);
</script>
```

## Render links for the link parameters

By using the [link parameter](https://docs.uniform.app/docs/guides/models/components/parameters#link)
on components, editors can set links to other nodes.
This ensures valid URLs even when the linked node is moved to another location within the project map.
How these links are rendered in the frontend application is up to the developer to decide and implement.

For framework-specific examples of rendering a link value with the SDK helpers, including how to access the project map node id, dynamic input values, and project map id, see [Link Parameter Utilities](https://docs.uniform.app/docs/sdk/parameter-utilities/link-parameters).

## Generate sitemap.xml

Usually sitemap generation is your web framework task (also more reliable because of [dynamic pages exceptions](https://docs.uniform.app/docs/guides/composition/url-management/routing#dynamic-routes)).
But you can use Project Map API directly to fetch whole tree (tree or flat structure) data to construct it your self.

**Next.js**

Next.js framework provides three ways to achieve it:

1. [Manual static file upload](https://nextjs.org/learn/seo/crawling-and-indexing/xml-sitemaps)
2. [Generate via getServerSideProps](https://nextjs.org/learn/seo/crawling-and-indexing/xml-sitemaps) — This is the only option where you'd need to use Project Map API
3. **_Preferred option_:** Generate via npm package [next-sitemap](https://www.npmjs.com/package/next-sitemap).

**Nuxt**

You can use the [Nuxt Sitemap Module](https://sitemap.nuxtjs.org/) to generate a sitemap for your Nuxt app.

## Generate navigation from project map

The tree-like hierarchical structure of nodes in a project map make it easy to render
navigational components using the project map client.
Example use cases for navigation could be:

- Global navigation: Use project maps to render a main navigation or footer navigation
- Local navigation: Show links to sibling or child nodes of a specific node.
- Breadcrumb navigation: Show the trail of parent nodes of a specific node (such as `Home > Company > About us`).

> **Advanced or custom navigation:**
>
> If you need to control the structure or display, or need to enrich your navigation with content or personalized links, Uniform recommends you create custom [Canvas components](https://docs.uniform.app/docs/guides/models/components) that represent your navigation UI.
> This gives you a high level of flexibility as you can leverage all Canvas capabilities.
> Use [link parameters](https://docs.uniform.app/docs/guides/models/components/parameters#link) in your components to connect your links with the project map.

To get the list of the top level project map nodes (for example, for a global navigation), you can use `ProjectMapClient.getNodes` and set the `depth` parameter to `1`:

_For the US region:_

```typescript
const projectMapClient = new ProjectMapClient({
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

const response = await projectMapClient.getNodes({
  depth: 1,
});
```

_For the EU region:_

```typescript
const projectMapClient = new ProjectMapClient({
  apiHost: 'https://eu.uniform.app',  
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

const response = await projectMapClient.getNodes({
  depth: 1,
});
```

> **Use an AI coding assistant:**
>
> The [`uniform-navigation`](https://github.com/uniformdev/agent-skills/tree/main/skills/uniform-navigation) agent skill teaches coding assistants such as Claude Code, Codex, Cursor, and Copilot how to model and build header navigation that editors can author and reorder: dropdowns, mega menus, and mobile drawers. To install it, see [Uniform agent skills](https://docs.uniform.app/docs/guides/ai/agent-skills).

To get the ancestors of a project map node (for example, for breadcrumb navigation), you can use `ProjectMapClient.getNodes` and set the `includeAncestors` parameter to `true`:

_For the US region:_

```typescript
const projectMapClient = new ProjectMapClient({
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

const response = await projectMapClient.getNodes({
  path: "/my-category/my-subcategory/my-page",
  includeAncestors: true,
});
```

_For the EU region:_

```typescript
const projectMapClient = new ProjectMapClient({
  apiHost: 'https://eu.uniform.app',  
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

const response = await projectMapClient.getNodes({
  path: "/my-category/my-subcategory/my-page",
  includeAncestors: true,
});
```

> **Use an AI coding assistant:**
>
> The [`uniform-breadcrumbs`](https://github.com/uniformdev/agent-skills/tree/main/skills/uniform-breadcrumbs) agent skill teaches coding assistants such as Claude Code, Codex, Cursor, and Copilot how to build a breadcrumb trail from the project map: resolving the current node, walking its ancestors, and titling and linking each crumb. To install it, see [Uniform agent skills](https://docs.uniform.app/docs/guides/ai/agent-skills).
