Documentation Index
Fetch the complete documentation index at: https://mintlify.com/tailor-platform/app-shell/llms.txt
Use this file to discover all available pages before exploring further.
hidden() is a helper function that returns a guard result indicating access should be denied with a 404 response.
Type Signature
const hidden: () => GuardResult;
type GuardResult = { type: "hidden" };
Behavior
When a guard returns hidden():
- Route is inaccessible: The route cannot be accessed via URL or navigation
- 404 response: A 404 Not Found error is thrown
- Guard chain stops: Subsequent guards are not evaluated
- Hidden from navigation: The route does not appear in sidebars or command palette
- No redirect: The user stays on the current page or sees the error boundary
Basic Usage
import { hidden } from "@tailor-platform/app-shell";
const denyAccess: Guard = () => {
return hidden();
};
Conditional Access Control
Most commonly used with conditional logic to hide routes from unauthorized users:
import { pass, hidden } from "@tailor-platform/app-shell";
const requireAdmin: Guard = ({ context }) => {
if (context.currentUser?.role === "admin") {
return pass();
}
return hidden(); // Non-admins see 404
};
defineModule({
path: "admin",
component: AdminDashboard,
resources: [adminResources],
guards: [requireAdmin]
});
Common Use Cases
Role-Based Access
import { type Guard, pass, hidden } from "@tailor-platform/app-shell";
const requireRole = (role: string): Guard => {
return ({ context }) => {
if (context.currentUser?.role !== role) {
return hidden(); // Wrong role = 404
}
return pass();
};
};
defineResource({
path: "admin-settings",
component: AdminSettings,
guards: [requireRole("admin")]
});
Feature Flag
Hide features that are disabled:
import { type Guard, pass, hidden } from "@tailor-platform/app-shell";
const requireFeature = (feature: string): Guard => {
return ({ context }) => {
if (!context.featureFlags[feature]) {
return hidden(); // Feature disabled = 404
}
return pass();
};
};
defineModule({
path: "beta",
component: BetaFeatures,
resources: [betaResources],
guards: [requireFeature("beta-access")]
});
Plan-Based Features
Hide premium features from free users:
import { type Guard, pass, hidden } from "@tailor-platform/app-shell";
const requirePremium: Guard = ({ context }) => {
if (context.currentUser?.plan !== "premium") {
return hidden(); // Free users see 404
}
return pass();
};
defineResource({
path: "advanced-analytics",
component: AdvancedAnalytics,
guards: [requirePremium]
});
Permission-Based Access (Async)
import { type Guard, pass, hidden } from "@tailor-platform/app-shell";
const requirePermission = (permission: string): Guard => {
return async ({ context }) => {
const hasPermission = await context.apiClient.checkPermission(permission);
if (!hasPermission) {
return hidden();
}
return pass();
};
};
defineResource({
path: "sensitive-data",
component: SensitiveDataPage,
guards: [requirePermission("data.sensitive.view")]
});
When to Use hidden() vs redirectTo()
Use hidden() when:
- The route should appear to not exist for unauthorized users
- You want to prevent route discovery through URL guessing
- The user should not know the feature exists (e.g., beta features, premium features)
- Access is based on roles, permissions, or feature flags
Use redirectTo() when:
- The user needs authentication (redirect to login)
- You want to guide users to the correct page (e.g., redirect to dashboard)
- The route exists but requires a specific state (e.g., onboarding incomplete)
Example: Combined Guards
import { type Guard, pass, hidden, redirectTo } from "@tailor-platform/app-shell";
const requireAuth: Guard = ({ context }) => {
if (!context.currentUser) {
return redirectTo("/login"); // Redirect unauthenticated users
}
return pass();
};
const requireAdmin: Guard = ({ context }) => {
if (context.currentUser?.role !== "admin") {
return hidden(); // Hide from non-admins (they're authenticated)
}
return pass();
};
defineModule({
path: "admin",
component: AdminDashboard,
resources: [adminResources],
guards: [
requireAuth, // First check authentication
requireAdmin // Then check admin role
]
});
Effect on UI
When a route is hidden:
The route will not appear in sidebar menus:
// Admin route only visible to admins
const adminModule = defineModule({
path: "admin",
component: AdminDashboard,
resources: [adminResources],
guards: [requireAdmin] // Non-admins won't see this in sidebar
});
Command Palette
Hidden routes are excluded from command palette search results.
Direct URL Access
Attempting to navigate directly to a hidden route shows a 404 error.
Return Value
hidden() returns a GuardResult object:
This object is processed by AppShell’s routing system to throw a 404 error.
Error Handling
The 404 error can be caught by error boundaries:
import { useRouteError } from "@tailor-platform/app-shell";
const CustomErrorBoundary = () => {
const error = useRouteError();
// Check if it's a 404 from hidden guard
const is404 = error instanceof Response && error.status === 404;
if (is404) {
return <div>Page not found</div>;
}
return <div>An error occurred</div>;
};
defineModule({
path: "admin",
component: AdminDashboard,
resources: [adminResources],
guards: [requireAdmin],
errorBoundary: <CustomErrorBoundary />
});
See Also