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

[WIP] Brought back APIs, moved route generation to proper v7 convention, allowed for user decision on SSR #2449

Open
wants to merge 4 commits into
base: miho-react-router-7-poc
Choose a base branch
from

Conversation

AlemTuzlak
Copy link

@AlemTuzlak AlemTuzlak commented Jan 11, 2025

Description

Continuation of moving to react-router v7 PoC with some improvements, notably:

  • Allow for full on SSR (depending on if the user wants it or not
  • Allow for expanded routing convention where you could create layouts etc.

Select what type of change this PR introduces:

  1. Just code/docs improvement (no functional change).
  2. Bug fix (non-breaking change which fixes an issue).
  3. New feature (non-breaking change which adds functionality).
  4. Breaking change (fix or feature that would cause existing functionality to not work as expected).

Update Waspc ChangeLog and version if needed

If you did a bug fix, new feature, or breaking change, that affects waspc, make sure you satisfy the following:

  1. I updated ChangeLog.md with description of the change this PR introduces.
  2. I bumped waspc version in waspc.cabal to reflect changes I introduced, with regards to the version of the latest wasp release, if the bump was needed.

Update example apps if needed

If you did code changes and added a new feature or modified an existing feature, make sure you satisfy the following:

  1. I updated waspc/examples/todoApp as needed (updated modified feature or added new feature) and manually checked it works correctly.
  2. I updated waspc/headless-test/examples/todoApp and its e2e tests as needed (updated modified feature and its tests or added new feature and new tests for it).

import { router } from './router'

export default function Component() {
return router;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reason this was removed was due to the fact that you would create a browserRouter inside the already existing react-router router. I am not sure if this worked before, I'd expect it to not work due to nested routers but maybe it did.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

entry.client.ts creates the HydratedRouter and wraps the whole app with it

}

export const ErrorBoundary = DefaultRootErrorBoundary
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brought back the error boundary for the whole app

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed in favor of routes.ts

{=/ isExternalAuthEnabled =}
]
const userDefinedRoutes = Object.entries(routes).map(([routeKey, route]) => {
// TODO: This should be the path to the route module file (eg. /src/routes/home.tsx)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would need a little bit of help here, the current api of the route function is to expect the url segment as the first arg and the path to the module as the second, so eg:

route("login", "./app/login.tsx")

Not sure how you generate routes but I'm pretty sure you have to have a path to the actual route, all you have to do is replace the route argument with the actual correct thing, so just adapt

export const routeNameToRouteComponent = {
  {=# routes =}
  {= name =}: {= targetComponent =},
  {=/ routes =}
} as const;

to actually work with modules I guess

@@ -16,7 +16,7 @@ const _waspUserProvidedConfig = {};

const defaultViteConfig = {
base: "{= baseDir =}",
plugins: [reactRouter()],
plugins: [reactRouterDevtools(), reactRouter()],
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sneakily added in dev tools for react-router, don't tell the contributors! Jokes aside, remove if you don't like it, or think it's useless

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this file is a bit suspicious in terms of what it should look like, I see you use axios, which is perfectly fine, but using browser APIs locks you into drumroll client-side rendering.

I would need to understand what exactly is the scope of this functionality to help out and change it, from what I see it's supposed to handle authentication. If that's the case and you want to support both SSR and CSR you will need to do the following:

  1. Add two storages (session storage on the server, the same storage you've been using up until now for the client)
  2. Make the code understand the operation context and fetch from the correct storage.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking at this for a second I realise there's no need to change this file, but rather the storage interface, I'll elaborate more there

@@ -6,45 +6,50 @@ export type DataStore = {
clear(): void
}

function createLocalStorageDataStore(prefix: string): DataStore {
function createStorageDataStore(prefix: string): DataStore {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this generic as if you want to support SSR you'll need to not rely on web api's

function ensureLocalStorageIsAvailable(): void {
if (!window || !window.localStorage) {
throw new Error('Local storage is not available.')
// TODO: Make this function work in the server context as well.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will be a bit trickier, if you want to use the react-router built in session handling it would require the request object as well which would have to be piped to here. Up for discussion with you guys what you'd want to do

Comment on lines +5 to +11
{=# ssr.isDefined =}
isSSR = Boolean("{= ssr.value =}")
{=/ ssr.isDefined =},

export default {
appDirectory: "src",
ssr: false,
ssr: isSSR,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just a good ol' JS dev, I don't speak in haskell, but you'll get the idea

Comment on lines +27 to +34
layout(
// TODO: This should maybe always be defined, if not,
// TODO: the code should be (if defined => layout, otherwise => spread the routes normally in the array)
{=# rootComponent.isDefined =}
"{= rootComponent.importIdentifier =}"
{=/ rootComponent.isDefined =},
[...waspDefinedRoutes, ...userDefinedRoutes]
),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brought back the functionality from the router.ts but the issue is that layout needs to be defined, so it will either be always defined OR:

isDefined ? layout(path, children) : children

Copy link
Author

@AlemTuzlak AlemTuzlak Jan 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, another cool this opens up as a possibility for you guys is to add layout routes etc as functionalities in wasp, eg in your wasp config you could do something like:

layout RootLayout { path: "/", to: MainPage }
route RootRoute { path: "/", to: MainPage, layout: RootLayout }

This would increase complexity obviously on your side, but would also make users happy, I'd assume

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

Successfully merging this pull request may close these issues.

1 participant