Home

Innovative Tech Development

Implementing Dynamic Routing in a Commerce Application with Sanity's Router and React

Building

a

seamless,

efficient

routing

system

for

a

commerce

application

can

significantly

enhance

user

experience

and

application

performance.

This

article

dives

deep

into

the

journey

of

integrating

Sanity's

router

with

React

to

develop

a

dynamic,

scalable

routing

framework

tailored

for

a

commerce

tool.

Image

Integrating Sanity's router into our commerce application wasn't just about coding—it involved significant research and exploration. Much of the development time was spent delving into API documentation and searching for practical examples to understand how best to utilise Sanity's routing capabilities within our React application.

The primary research began with exploring the Sanity GitHub repository, which hosts the latest code for the router package. The directory of interest was sanity/src/router, where the core routing logic and utilities are maintained. This exploration was crucial for understanding the underlying mechanics of Sanity's routing system and how it could be leveraged to meet our application's specific needs.

A breakthrough came from a demo within the README file at sanity/src/router/README.md on GitHub. This demo provided a glimpse into the practical implementation of the router, showcasing how routes could be dynamically created and managed within a Sanity plugin. It served as a vital reference point, translating the theoretical aspects of the API documentation into a tangible example that could be adapted for our purposes.

Additional documentation from Sanity's official site played a pivotal role throughout this journey. The pages on Router and route provided detailed insights into the API's capabilities, options, and configurations. These resources were instrumental in understanding the nuances of route creation, navigation handling, and the integration of dynamic routing within our commerce tool.

The process was ultimately rewarding despite the lack of straightforward examples and the challenge of piecing together information from various sources. It pushed the boundaries of what we could achieve with Sanity's router, developing a flexible, dynamic routing system tailored specifically for our commerce application. The experience underscores the importance of thorough research, experimentation, and leveraging available resources to implement practical solutions in software development.

This example leverages TypeScript for solid typing, ensuring our application's navigation logic is clear and error-resistant.

Defining Constants and Types

First, we define the constant settings that will underpin our routing and view logic:

type ViewType = "order" | "product" | "customer";
type ActionType = "create" | "view" | "edit";

type StateType = {
  action?: ActionType;
  id?: string;
  view: ViewType;
};

enum CommerceRoutes {
  view = "/view/:view",
  create = "/view/:view/:action",
  action = "/view/:view/:action/:id",
}

export { CommerceRoutes };
export type { ViewType, ActionType, StateType };

These constants and types (ViewType, ActionType, and StateType) define the possible views (like orders or products), actions (such as create or edit), and the state shape our application can take. CommerceRoutes is an enumeration that maps our route patterns to meaningful names, making our routing table easy to read and maintain.

Building the Commerce Tool

Next, we create a new tool that incorporates these routes:

import { route } from '@sanity/base/router'

const commerceTool = () => {
  return {
    title: "Commerce",
    name: "commerce-tool",
    component: () => CommerceTool(),
    router: route.create("/", [
      ...Object.values(CommerceRoutes).map((item) => route.create(item)),
    ]),
  };
}; 

This tool, named "Commerce", uses Sanity's router to define its routing logic. By iterating over our CommerceRoutes enumeration, we dynamically create routes for our application, keeping our code DRY and routing table flexible.

Creating a Plugin

To encapsulate our tool within a broader application context, we wrap it in a plugin:

import { definePlugin } from 'sanity'

const commercePlugin = () =>
  definePlugin({
    name: "commerce-plugin",
    tools: [commerceTool()],
  });

export { commercePlugin };

This "commerce-plugin" plugin can be easily integrated into any Sanity studio, allowing for quick setup and scalability across different workspaces.

Defining the Main View

Finally, we define the main view component that renders UI based on the current route's state:

import { ActionType, ViewType, StateType } from "@/studio/plugins/commerce/constants";
import dynamic from "next/dynamic";

type Props = {
  state: StateType;
};

const viewMap: Partial<Record<ViewType, Record<ActionType, any>>> = {
  product: {
    edit: dynamic(() => import("./product/product-edit-view")),
    view: dynamic(() => import("./product/product-view")),
    create: dynamic(() => import("./product/product-create-view")),
  },
  // Additional view mappings can be added here
};

export default function View({ state }: Props) {
  const Component = state.action ? viewMap[state.view]?.[state.action] : null;
  return Component ? <Component state={state} /> : <div>Not found</div>;
}

This component, View, uses a dynamic import strategy to load the appropriate component based on the current state. This lazy-loading approach ensures that our application only loads the necessary code, improving performance.

Image

Conclusion

We've created a scalable, maintainable, and performance-optimised routing system by integrating Sanity's router with a dynamic component loading strategy in a TypeScript React application. This approach allows for clear separation of concerns, easy debugging, and a solid foundation for expanding our commerce application.

Published by

Oybek Khalikovic

Oybek Khalikovic

CTO, Karve Digital

Your vision our expertise
Let's Talk
[email protected]+971 (0)54 421 11 80Building A2 IFZA Business Park Dubai Silicon Oasis, Dubai
[DESIGNED IN CODE]
KARVEDIGITAL © 2024