Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any support for base, base_url or basename? #102

Closed
carlvoller opened this issue Jul 8, 2023 · 2 comments
Closed

Any support for base, base_url or basename? #102

carlvoller opened this issue Jul 8, 2023 · 2 comments

Comments

@carlvoller
Copy link

Hi, I was wondering if this project had any way to implement support for Vite's base or react-router's basename properties. I can't deploy my site at the root of the domain and need to set a subdirectory as the root instead. I tried following the react-router-custom-path example but I don't think that quite supports my need.

Ideally what I want to achieve is when the user navigates to /subdirectory/, they should be returned the page in /src/pages/index.tsx. I tried creating a custom router in routes.tsx to set the basename property on createBrowserRouter() but that doesn't appear to route the files in /src/pages correctly.

Would really appreciate some guidance on this, this project is so close to perfect for me! Thank you for your time, I hope your day has been great!

My current routes.tsx for reference:

import { Fragment } from "react";
import {
  createBrowserRouter, Outlet, RouterProvider, useLocation,
} from "react-router-dom";
import type { ActionFunction, RouteObject, LoaderFunction } from "react-router-dom";

import { generateModalRoutes, generatePreservedRoutes, generateRegularRoutes } from "@generouted/react-router/core";

type Element = () => JSX.Element;
type Module = { default: Element; Loader: LoaderFunction; Action: ActionFunction; Catch: Element };

const PRESERVED = import.meta.glob<Module>("/src/pages/(_app|404).{jsx,tsx}", { eager: true });
const MODALS = import.meta.glob<Pick<Module, "default">>("/src/pages/**/[+]*.{jsx,tsx}", { eager: true });
const ROUTES = import.meta.glob<Module>(["/src/pages/**/[\\w[-]*.{jsx,tsx}", "!**/(_app|404).*"], {
  eager: true,
});

const preservedRoutes = generatePreservedRoutes<Element>(PRESERVED);
const modalRoutes = generateModalRoutes<Element>(MODALS);

const regularRoutes = generateRegularRoutes<RouteObject, Partial<Module>>(ROUTES, (module, key) => {

  console.log(key);
  const index = /index\.(jsx|tsx)$/.test(key) && !key.includes("pages/index") ? { index: true } : {};

  return {
    ...index,
    Component: module?.default,
    ErrorBoundary: module?.Catch,
    loader: module?.Loader,
    action: module?.Action,
  };

});

const App = preservedRoutes?._app || Outlet;
const NotFound = preservedRoutes?.["404"] || Fragment;

export const routes = [{ element: <App />, children: [...regularRoutes, { path: "*", element: <NotFound /> }] }];
export const Routes = function Routes() {

  return (
    <RouterProvider
      router={createBrowserRouter(routes, {
        basename: import.meta.env.BASE_URL,
      })}
    />
  );

};

export const Modals = function Modals() {

  const current = useLocation().state?.modal;
  const Modal = modalRoutes[current] || Fragment;
  return <Modal />;

};
@oedotme
Copy link
Owner

oedotme commented Jul 9, 2023

Hey @carlvoller, thanks for your comment!

Yes indeed, the react-router-custom-path example is for a custom directory structure which is different than what you're trying to do here.

The prefixed base/basename path however is not specific to generouted but from what I understand and as you mentioned, it should work with 1. Vite using base option, mainly so the public assets are served as expected. 2. react-router-dom using basename option, to correctly resolve and navigate the routes. I believe you'll need to leverage both to deploy on a non-root domain sub-path.

Here's a reference to the updates needed to achieve what you wanted:

// vite.config.ts

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import generouted from '@generouted/react-router/plugin'

export default defineConfig({
  plugins: [react(), generouted()],
  base: '/sub/',
})

For the router basename config, instead of having a custom src/routes.tsx, you can update your app entry as following:

// src/main.tsx

import { createRoot } from 'react-dom/client'
import { RouterProvider, createBrowserRouter } from 'react-router-dom'
import { routes } from '@generouted/react-router'

const Routes = () => <RouterProvider router={createBrowserRouter(routes, { basename: '/sub' })} />

const container = document.getElementById('app')!
createRoot(container).render(<Routes />)

Here's an example the pages matching the base prefixed routes:

  • /subsrc/pages/index.tsx
  • /sub/aboutsrc/pages/about.tsx
  • /sub/postssrc/pages/posts/index.tsx

Hope that helps, have a nice day!

@carlvoller
Copy link
Author

Hi @oedotme,

That did the trick! Thank you so much for your help! I really appreciate it.

Have a great day to you too 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants