Testimonials
The page that lists customer reviews of the store with a sort control.
Framework: TanStack Start
This page is written for TanStack Start, the default and currently supported framework. See what depends on the framework.
The customer reads what customers wrote about the store as a whole (not one product), and can sort the reviews. Everyone can open it. Customise it to retitle the page or wrap it in your own layout.
URL
| Pattern | Example |
|---|---|
/{-$locale}/testimonials | /testimonials, /ar/testimonials?sort=top_rating |
| Param | Type | Notes |
|---|---|---|
locale | string (optional) | ar in the example above |
sort (search) | string | latest (default), oldest, top_rating or bottom_rating. The route does not validate it; the page component reads and writes it. |
Try it
This is the testimonials as the engine renders it, running against the demo store. Switch the language or the width.
/ar/testimonialsOpen/{-$locale}/testimonials- locale = ar
- path = /testimonials
Route file
// @auto-generated
import { createFileRoute } from '@tanstack/react-router';
import { Testimonials } from '@salla.sa/twilight-theme-engine/routes/testimonials';
import type { TestimonialsPageProps } from '@salla.sa/twilight-theme-engine/routes/testimonials';
import { withHead } from '@salla.sa/twilight-theme-engine/tanstack';
export const Route = createFileRoute('/{-$locale}/testimonials')({
loader: ({ params }): Promise<TestimonialsPageProps> =>
Testimonials.loader({ locale: params.locale }),
head: withHead(Testimonials),
component: TestimonialsComponent,
});
function TestimonialsComponent() {
const data: TestimonialsPageProps = Route.useLoaderData();
return <Testimonials.Component {...data} />;
}To take the page over, delete the // @auto-generated line and edit the file. See Fork a built-in route.
A customised version
Set a fixed title with the loader's extend argument, and wrap the engine page in your own element:
export const Route = createFileRoute('/{-$locale}/testimonials')({
loader: ({ params }): Promise<TestimonialsPageProps> =>
Testimonials.loader({ locale: params.locale }, (data) => ({
page: { ...data.page, title: 'What our customers say' },
})),
head: withHead(Testimonials),
component: function TestimonialsRoute() {
const data: TestimonialsPageProps = Route.useLoaderData();
return (
<section className="my-reviews">
<Testimonials.Component {...data} />
</section>
);
},
});What it loads
The loader makes no API call. It returns { page: { slug, title } }, with the title from the blocks.home.testimonials translation. The reviews load in the browser through the SallaComments component, so they are not in the server HTML.
The head sets the title, description and language alternates.
Edge cases
- Sorting. The page reads
?sort=on mount. Each change rewrites the URL without a navigation (the loader does not run again) and reloads the list. An unknown value is passed through as is. - Empty list. Handled by
SallaComments, not by this route.
See also
- Loyalty, the previous page in More
- Product page, where one product's reviews live
- Product reviews, every product's reviews on one page
- Layout and components