Laravel Command to generate route endpoints that can be used in typescript fully threeshakable. **GenerateTypescriptRoutes.php** ```php getRoutesByName())->map(function ($route, $name) { $routeIngoreList = [ 'filament.', 'debugbar.', 'livewire.', 'ignition.', 'sanctum.csrf-cookie', ]; if (Str::startsWith($name, $routeIngoreList)) { return ''; } preg_match_all('/\{(.*?)\}/', $route->uri(), $args, PREG_SET_ORDER); $argstr = collect($args) ->map(fn ($a) => $this->mapReservedWord($a[1]) . ": string | number") ->add('query?: QueryParams') ->join(', '); $path = preg_replace_callback('/\{(.*?)\}/', function ($match) { $isOptional = strpos($match[1], '?') !== false; return '${' . str_replace('?', '', $this->mapReservedWord($match[1])) . ($isOptional ? " ?? ''" : '') . '}'; }, $route->uri()); if (substr($path, 0, 1) !== '/') { $path = '/'. $path; } $safeName = Str::snake(str_replace(['-', '.'], '_', $name)); return "/** {$name} */ export function route_to_{$safeName}({$argstr}) { return withQuery(`{$path}`, query); }\n"; })->filter()->join("\n"); $header = ' // _______ _______ __ _ _______ ______ _______ _______ _______ ______ // | || || | | || || _ | | _ || || || | // | ___|| ___|| |_| || ___|| | || | |_| ||_ _|| ___|| _ | // | | __ | |___ | || |___ | |_||_ | | | | | |___ | | | | // | || || ___|| _ || ___|| __ || | | | | ___|| |_| | // | |_| || |___ | | | || |___ | | | || _ | | | | |___ | | // |_______||_______||_| |__||_______||___| |_||__| |__| |___| |_______||______| // // Generated with: // php artisan app:generate-typescript-routes export type QueryParams = string | string[][] | Record | URLSearchParams | undefined; function withQuery(path: string, query: QueryParams) { const searchParams = new URLSearchParams(query); return `${path}${searchParams.size > 0 ? `?${searchParams.toString()}` : \'\'}`; } '; File::put(resource_path('js/routes.ts'), $header . "\n" . $contents); $this->info(resource_path('js/routes.ts') . ' succesfully generated'); } private function mapReservedWord($word) { $jsReservedWords = [ 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'let', 'new', 'null', 'return', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield', 'await', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static', ]; if (in_array($word, $jsReservedWords)) { return '_' . $word; } return $word; } } ``` **Example generated routes.ts** ```ts // _______ _______ __ _ _______ ______ _______ _______ _______ ______ // | || || | | || || _ | | _ || || || | // | ___|| ___|| |_| || ___|| | || | |_| ||_ _|| ___|| _ | // | | __ | |___ | || |___ | |_||_ | | | | | |___ | | | | // | || || ___|| _ || ___|| __ || | | | | ___|| |_| | // | |_| || |___ | | | || |___ | | | || _ | | | | |___ | | // |_______||_______||_| |__||_______||___| |_||__| |__| |___| |_______||______| // // Generated with: // php artisan app:generate-typescript-routes export type QueryParams = string | string[][] | Record | URLSearchParams | undefined; function withQuery(path: string, query: QueryParams) { const searchParams = new URLSearchParams(query); return `${path}${searchParams.size > 0 ? `?${searchParams.toString()}` : ''}`; } /** register */ export function route_to_register(query?: QueryParams) { return withQuery(`/register`, query); } /** login */ export function route_to_login(query?: QueryParams) { return withQuery(`/login`, query); } ``` **Usage** ```sh php artisan app:generate-typescript-routes ``` **App.vue** ```vue ``` **vite.config.js** ```js import { watch } from 'vite-plugin-watch'; export default defineConfig({ plugins: [ watch({ pattern: 'routes/{web,manage}.php', command: 'php artisan app:generate-typescript-routes', }), ], }); ```