{"id":17965,"library":"stx-router","title":"STX Router","description":"STX Router is a file-based routing solution specifically designed for the Stacks.js full-stack framework. It facilitates automatic discovery of `.stx` templates, enables nested layouts, offers typed route parameters for enhanced developer experience and compile-time safety, supports middleware for request processing, and provides robust client-side SPA navigation. As of version 0.2.12, the package is in active pre-1.0 development, integrating seamlessly into the Stacks.js ecosystem which leverages TypeScript and Bun for performance and type-safety. The project generally follows a convention-over-configuration philosophy, aiming for rapid application development. Its current release cadence is frequent, indicating ongoing feature development and potential for breaking changes between minor versions as it approaches a stable 1.0 release.","status":"active","version":"0.2.12","language":"javascript","source_language":"en","source_url":"https://github.com/stacksjs/stx","tags":["javascript","router","file-based","middleware","typed-routes","nested-layouts","spa","bun","stx","typescript"],"install":[{"cmd":"npm install stx-router","lang":"bash","label":"npm"},{"cmd":"yarn add stx-router","lang":"bash","label":"yarn"},{"cmd":"pnpm add stx-router","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"STX Router is primarily designed for ESM environments and TypeScript, aligning with the Stacks.js framework's architecture.","wrong":"const { createRouter } = require('@stacksjs/router')","symbol":"createRouter","correct":"import { createRouter } from '@stacksjs/router'"},{"note":"Middleware functions are typically defined using `defineMiddleware` for proper integration with the routing pipeline and type inference.","wrong":"import defineMiddleware from '@stacksjs/router'","symbol":"defineMiddleware","correct":"import { defineMiddleware } from '@stacksjs/router'"},{"note":"Importing types like `RouteContext` should always use `import type` to ensure they are stripped during compilation and do not introduce runtime overhead.","symbol":"RouteContext","correct":"import type { RouteContext } from '@stacksjs/router'"}],"quickstart":{"code":"import { createRouter, defineMiddleware } from '@stacksjs/router';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Define a simple authentication middleware\nconst authMiddleware = defineMiddleware((req, res, next) => {\n  const isAuthenticated = req.headers.get('authorization') === 'Bearer my-secret-token';\n  if (isAuthenticated) {\n    console.log('User is authenticated');\n    next();\n  } else {\n    console.warn('Authentication failed: Missing or invalid token');\n    res.status(401).send('Unauthorized');\n  }\n});\n\n// Imagine your .stx templates are in a 'views' directory\n// For a file-based router, you'd typically have files like:\n// views/index.stx, views/users/[id].stx, views/admin/dashboard.stx\nconst router = createRouter({\n  routes: join(__dirname, 'views'), // Points to your .stx template directory\n  middleware: {\n    '/admin/*': [authMiddleware], // Apply authMiddleware to all /admin routes\n  },\n  // You might define custom error handlers or other router options here\n  onNotFound: (req, res) => {\n    res.status(404).send('Custom 404 Not Found Page');\n  },\n});\n\n// Example: How to manually handle a request (in a server context, e.g., Bun.serve)\n// In a real Stacks.js app, this would be abstracted away by the framework's server.\nasync function handleRequest(request: Request) {\n  const url = new URL(request.url);\n  console.log(`Incoming request: ${request.method} ${url.pathname}`);\n\n  // Simulate router matching and processing\n  // In a full Stacks.js app, this would trigger .stx template rendering\n  const response = await router.handle(request);\n\n  // For demonstration, a simple placeholder response if router doesn't explicitly respond\n  if (!response.headers.has('X-Router-Handled')) {\n    if (url.pathname === '/') {\n      return new Response('Welcome to the STX App!', { status: 200 });\n    } else if (url.pathname.startsWith('/users/')) {\n      const userId = url.pathname.split('/').pop();\n      return new Response(`User profile for ID: ${userId}`, { status: 200 });\n    }\n    return new Response('Default response for unmatched routes or handled by custom 404', { status: 404 });\n  }\n  return response;\n}\n\n// This part would typically be part of your Stacks.js server setup\n// Bun.serve({\n//   fetch: handleRequest,\n//   port: 3000,\n// });\n\n// console.log('STX Router example server running on http://localhost:3000');\n\n// To test manually:\n// await handleRequest(new Request('http://localhost:3000/'));\n// await handleRequest(new Request('http://localhost:3000/users/123'));\n// await handleRequest(new Request('http://localhost:3000/admin/dashboard', { headers: { 'Authorization': 'Bearer my-secret-token' } }));\n// await handleRequest(new Request('http://localhost:3000/admin/settings')); // Should be unauthorized\n// await handleRequest(new Request('http://localhost:3000/nonexistent')); // Should trigger custom 404","lang":"typescript","description":"This quickstart demonstrates how to initialize `stx-router` with a file-based route directory, apply a simple authentication middleware to protected paths, and shows a basic request handling flow within a simulated Stacks.js server environment. It highlights the use of `createRouter` and `defineMiddleware`."},"warnings":[{"fix":"Always review the release notes or changelog when upgrading minor versions. Pin exact versions in your `package.json` to prevent unexpected breaking changes in production, and test thoroughly before deploying updates.","message":"As a pre-1.0 release, `stx-router` may introduce breaking changes in minor versions (e.g., 0.2.x to 0.3.x). APIs, configuration options, and internal behaviors are subject to change without strict adherence to semantic versioning until a stable 1.0 release.","severity":"breaking","affected_versions":">=0.1.0"},{"fix":"Consult the Stacks.js documentation for the exact file-based routing conventions, especially regarding dynamic segments (e.g., `[id].stx`), nested layouts, and index files. Ensure your template directory path is correctly configured in `createRouter`.","message":"File-based routing relies on specific directory structures and naming conventions for `.stx` templates. Deviating from these conventions will result in routes not being discovered or matched correctly, leading to 404 errors.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Carefully define your middleware paths and ensure they are specified in the correct order in your router configuration. Use logging within your middleware to verify their execution flow for specific requests. Broad wildcard (`*`) paths should be used with caution.","message":"Middleware execution order and application scope can be a common source of bugs. Middleware might not execute for certain routes, or the order of execution might be unexpected, especially with overlapping paths.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Always validate and parse route parameters explicitly in your route handlers or middleware, especially when converting between string path segments and numerical/boolean types. Leverage TypeScript's type inference and type guards to handle parameter types safely.","message":"Typed route parameters, while beneficial, require careful definition in your route files (or inferred types). Incorrectly accessing or assuming the type of a route parameter (e.g., treating a string ID as a number without parsing) can lead to runtime `TypeError`s.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Verify that a corresponding `.stx` file exists for the requested path (e.g., `views/your/path.stx` or `views/your/[param].stx`). Check the `routes` configuration in `createRouter` to ensure it points to the correct base directory. Also, confirm no typos in the URL or route definition.","cause":"The requested URL path does not match any defined file-based route in your `.stx` template directory, or the router configuration is incorrect.","error":"Error: Route not found for path '/your/path'"},{"fix":"Ensure that the route being handled actually defines dynamic parameters (e.g., `/users/:id`). Before accessing `params`, consider optional chaining (`req.params?.id`) or a null/undefined check to handle cases where parameters might not exist gracefully.","cause":"Attempting to access `req.params` or `ctx.params` when no route parameters are present for the matched route, or when the request context (`ctx`/`req`) is not correctly populated by the router.","error":"TypeError: Cannot read properties of undefined (reading 'params')"},{"fix":"Ensure you are using `import { defineMiddleware } from '@stacksjs/router'` for named exports. If the module primarily offers a default export, you would use `import Router from '@stacksjs/router'` (though `stx-router` uses named exports). Also, verify your project's `tsconfig.json` and `package.json` (`\"type\": \"module\"`) are correctly configured for ESM.","cause":"This usually indicates a mismatch between CommonJS `require()` syntax and an ESM module, or an incorrect named import from a module that uses default exports (or vice-versa).","error":"SyntaxError: Named export 'defineMiddleware' not found in module '@stacksjs/router'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}