Brand products page

The SEO short URL for a brand, which redirects to the brand page.

Framework: TanStack Start

This page is written for TanStack Start, the default and currently supported framework. See what depends on the framework.

Some links to a brand use the form /$slug/brand-{$id}. The customer never sees a page here: the route redirects straight to the brand page at /brands/$id. Customise it only if you want the brand's products to appear at this URL, or to redirect somewhere else.

URL

PatternExampleGoes to
/$slug/brand-{$id}/nike/brand-77/ar/brands/77
/{locale}/$slug/brand-{$id}/en/nike/brand-77/en/brands/77

Params

NameTypeExampleDescription
slugstringnikeIgnored. It only makes the path match the pattern.
idstring77The brand id, written brand-77.
localestring | undefinedenOptional. Without it the redirect uses the fallback locale ar (locale prefix).

There are no search params, and a query string on the short URL is not carried over.

Route file

It has no component and no head, only a loader that redirects.

app/routes/$slug.brand-$id.tsx
// @auto-generated
import { createFileRoute } from '@tanstack/react-router';
import { slugBrandRedirectLoader } from '@salla.sa/twilight-theme-engine/routes/seo-redirects';

export const Route = createFileRoute('/{-$locale}/$slug/brand-{$id}')({
  loader: ({ params }) =>
    slugBrandRedirectLoader({
      params: { slug: params.slug, id: params.id, locale: params.locale },
    }),
});

To take it over, write your own file and map the path in app/routes.ts (Fork a built-in route).

A customised version

This renders the brand's product list at the short URL, so the address does not change. It uses the same loader as the brand page. The engine head sets no canonical tag for brands, so two URLs with the same list can compete in search results; keep the redirect unless you add a canonical yourself.

app/routes/brand-products.tsx
import { createFileRoute } from '@tanstack/react-router';
import {
  ProductListing,
  type ProductListLoaderData,
} from '@salla.sa/twilight-theme-engine/routes/product-listing';
import { withHead } from '@salla.sa/twilight-theme-engine/tanstack';

export const Route = createFileRoute('/{-$locale}/$slug/brand-{$id}')({
  validateSearch: (search: Record<string, unknown>) => {
    const page = Number(search.page) || 1;
    const sort = (search.sort as string) || undefined;
    return { ...(page > 1 ? { page } : {}), ...(sort ? { sort } : {}) };
  },
  loaderDeps: ({ search }) => ({ page: search.page, sort: search.sort }),
  loader: ({ deps, params }): Promise<ProductListLoaderData> =>
    ProductListing.loader({
      params: { source: 'brands', id: params.id },
      search: { page: deps.page, sort: deps.sort },
      locale: params.locale,
    }),
  head: withHead(ProductListing),
  component: BrandProductsComponent,
});

function BrandProductsComponent() {
  const data: ProductListLoaderData = Route.useLoaderData();
  return <ProductListing.Component {...data} />;
}

What it loads

Nothing. The loader redirects to /{locale}/brands/{id} before any data is requested. The brand and its products load on the brand page.

Head and SEO

None, because no page is rendered. A crawler that follows the redirect ends up on the brand page and its head.

Edge cases

  • Redirect timing. It happens while the route loads: on the server for a first request, in the browser for client navigation.
  • No locale in the URL. The redirect uses ar, not the customer's language.
  • Unknown brand id. The redirect happens first, so the 404 comes from the brand page.
  • Slug is never checked. /anything/brand-77 redirects like the real slug.

See also

On this page