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

React hybrid routing #4710

Closed
23 tasks done
mshabarov opened this issue Nov 16, 2023 · 7 comments
Closed
23 tasks done

React hybrid routing #4710

mshabarov opened this issue Nov 16, 2023 · 7 comments
Labels

Comments

@mshabarov
Copy link
Contributor

mshabarov commented Nov 16, 2023

Description

Support routing to Flow views in React+Hilla applications using React Router.

Use cases

As a developer
I want to extend my React+Hilla application with server-side Flow views
So that I can benefit from Flow provided features, e.g. server-side navigation, Push and others.

As a developer
I want to extend my Flow application with React-based views/components using Hilla
So that I can benefit from using React where I want.

Acceptance criteria

  • React Router is integrated with the client-side and server-side Flow API in a same way as Vaadin Router does for Lit - @ClientCallable and methods in Flow.js, so that this integration doesn't bring major changes in Flow API.
  • Flow automatically generates on a build phase the codes for App.tsx and routes.tsx that is needed to connect React Router with the Flow API
  • Flow views are rendered inside the same client-side main layout that is used for existing Hilla views.
  • Adding Flow routes to React+Hilla apps need minor manual route customisation, which is well-documented in Hilla/Flow docs.
  • The integration supports the same routing features as the Vaadin Router integration with regards to e.g.
    • access control, including rerouting to a login page
    • navigation events and server-side navigation
    • beforeLeaveEvent.postpone()
    • handling context path and query parameter within navigation
    • routing exception handling
    • page titles
    • RouterLink and Anchor works the same way as for Vaadin Router
    • Push support
    • MPR
    • eager bootstrapping/rendering.

General criteria

  1. Flow applications that are not hybrids keep using Vaadin Router just like today.
  2. No need for a new routing API for Hilla, this isn't in scope of this project.
  3. This acceptance criteria covers the routing aspect of integration between Flow and React. Other aspects such as reusing 3rd party React components or using React as a template language from Flow are outside the scope of this project.
  4. React router integration is turned on by feature flag and Flow gives a clarification message to developer about the need of adding this feature flag.
  5. Flow tracks usage of hybrid configuration, including React+Hilla+Flow, Lit+Hilla+Flow cases.
  6. start.vaadin.com includes starter project for React+Hilla+Flow, having Hilla and Flow views and feature flag turned ON by default.

Auto-test in Flow https://github.com/vaadin/flow/tree/main/flow-tests/test-react-router

  • Limitations:
    • For using Lit based components/views one should enable @vaadin/router via reactEnabled=false config parameter.

Security (N/A)

  • Security implications have been taken into account (elaborate or link to product security requirement specification if there are implications)
@mshabarov mshabarov added acceptance criteria used for the acceptance criteria checklist Flow draft The acceptance criteria that is still WIP labels Nov 16, 2023
@mshabarov
Copy link
Contributor Author

navigation events and server-side navigation

Tested Hilla view -> Flow view navigation and navigation lifecycle events: BeforeLeaveEvent, BeforeEnterEvent , AfterNavigationEvent, including .addBeforeEnterListener() listener and forwardTo/rerouteTo methods. Works as expected.

@caalador
Copy link
Contributor

caalador commented Dec 5, 2023

Minimal documentation on getting the combination to work

Adding Flow to a Hilla-react project. (sample from CRM tutorial)

  • Add the flow managed dependency bom to pom.xml
    <properties>
        <java.version>17</java.version>
        <vaadin.version>24.3-SNAPSHOT</vaadin.version>
        <hilla.version>2.4.0</hilla.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Other pom imports like hilla -->
        </dependencies>
    </dependencyManagement>
  • Add the vaadin-core / vaadin dependency

      <dependency>
          <groupId>com.vaadin</groupId>
          <!-- Replace artifactId with vaadin-core to use only free components -->
          <artifactId>vaadin</artifactId>
      </dependency>
    
  • enable in src/main/resources/vaadin-featureflags.properties react for flow with:

    com.vaadin.experimental.reactRouter=true

  • Into frontend/routes.tsx add the serverSideRoutes object:

    
     import {serverSideRoutes} from "Frontend/generated/flow/Flow";
    
     ...
     export const routes = [
     	// Hilla definitions
     	...serverSideRoutes
     ]
    

    .crm_routes

     export const routes = [
       {
         element: <MainLayout />,
         handle: { title: 'Hilla CRM' },
         children: [
           { path: '/', element: <ContactsView />, handle: { title: 'Contacts' } },
           { path: '/about', element: <AboutView />, handle: { title: 'About' } },
           ...serverSideRoutes
         ],
       },
     ] as RouteObject[];
    

    [NOTE] The Frontend/generated/flow/Flow will be created when the project is run (node tasks will generate this)

  • Add Flow views with Route annotation.

  • Run project and Flow views can be navigated to.

@caalador
Copy link
Contributor

caalador commented Dec 7, 2023

Enabling eagerServerLoad in a Flow project works as expected. Also couldn't see any issues in a hilla-flow-react hybrid after enabling the flag.

@mshabarov
Copy link
Contributor Author

Access control seems to work fine for Flow view.

  1. Navigating from Hilla view to protected Flow view reroutes to login view if not authenticated.
  2. Navigating from Hilla view to unauthorised Flow view shows "Could not navigate to..." standard page.

However, one thing that doesn't work is navigating to Hilla view that is protected by a role.
For some reason, this view redirects back to login view, even after successful login.
Public Hilla view doesn't have this problem.

In the browser console log I see that UserInfoService returns "ROLE_USER" to the client and login method returns no errors.

Maybe my project configuration is incorrect. I followed this tutorial https://hilla.dev/docs/react/guides/security/spring-login.

Here is my test project.
proto-hilla-react-hybrid.zip

@platosha could you please verify my test project when appropriate ?

@caalador
Copy link
Contributor

  • Add hilla managed dependency bom to pom.xml
     <properties>
        ...
        <hilla.version>2.3.3</hilla.version>
     </properties>
 
    <dependencyManagement>
        <dependencies>
            <!-- Other pom imports like hilla -->
            <dependency>
                <groupId>dev.hilla</groupId>
                <artifactId>hilla-bom</artifactId>
                <version>${hilla.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
         </dependencies>
     </dependencyManagement>
  • Add hilla-react and hilla-spring-boot-starter dependencies
        <dependency>
            <groupId>dev.hilla</groupId>
            <artifactId>hilla-react</artifactId>
        </dependency>
        <!-- REPLACE vaadin-spring-boot-starter with hilla starter
         <dependency>
             <groupId>com.vaadin</groupId>
             <artifactId>vaadin-spring-boot-starter</artifactId>
        </dependency>-->
        <dependency>
            <groupId>dev.hilla</groupId>
            <artifactId>hilla-react-spring-boot-starter</artifactId>
         </dependency>
  • Change all vaadin-maven-plugin instances into hilla-maven-plugin
             <plugin>
-                <groupId>com.vaadin</groupId>
-                <artifactId>vaadin-maven-plugin</artifactId>
-                <version>${vaadin.version}</version>
+                <groupId>dev.hilla</groupId>
+                <artifactId>hilla-maven-plugin</artifactId>
+                <version>${hilla.version}</version>
                 <executions>
                     <execution>
                         <goals>
  • enable in src/main/resources/vaadin-featureflags.properties react for flow with:

com.vaadin.experimental.reactRouter=true

  • Run mvn hilla:init-app

  • Add into frontend/routes.tsx the serverSideRoutes object:

 import {serverSideRoutes} from "Frontend/generated/flow/Flow";

 ...
 export const routes = [
 	// Hilla definitions
 	...serverSideRoutes
 ]

mshabarov added a commit to vaadin/docs that referenced this issue Dec 12, 2023
* feat: Explain React Router integration for Vaadin Flow

Related-to vaadin/platform#4710

* lint fixes

* Apply suggestions from code review

Co-authored-by: Tarek Oraby <42799254+tarekoraby@users.noreply.github.com>
Co-authored-by: caalador <mikael.grankvist@vaadin.com>

* Moved to Integrations and added discussion id

* Clarification about dependencies and CRM

* Change page extension and order

* Update guide

* Initial Edits

* Second more thorough edits.

* Third full edits.

---------

Co-authored-by: Tarek Oraby <42799254+tarekoraby@users.noreply.github.com>
Co-authored-by: caalador <mikael.grankvist@vaadin.com>
Co-authored-by: russelljtdyer <6652767+russelljtdyer@users.noreply.github.com>
@platosha
Copy link
Contributor

So the issue with React routes redirect was that the server returns {"authorities": ["ROLE_USER"]}, whereas the Hilla helper expects {"roles": ["USER"]}. This implementation mismatch is not related with hybrid routing and is easy to workaround by specifying client-side auth configuration with getRoles.

@mshabarov mshabarov removed the draft The acceptance criteria that is still WIP label Dec 21, 2023
@vaadin-bot
Copy link
Contributor

This ticket/PR has been released with Vaadin 24.4.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: June 2024 (24.4) - Released
Development

No branches or pull requests

5 participants