@@ -841,6 +841,79 @@ test.describe("Middleware", () => {
841
841
appFixture . close ( ) ;
842
842
} ) ;
843
843
844
+ test ( "calls clientMiddleware when no loaders exist" , async ( { page } ) => {
845
+ let fixture = await createFixture ( {
846
+ files : {
847
+ "react-router.config.ts" : reactRouterConfig ( {
848
+ middleware : true ,
849
+ } ) ,
850
+ "vite.config.ts" : js `
851
+ import { defineConfig } from "vite";
852
+ import { reactRouter } from "@react-router/dev/vite";
853
+
854
+ export default defineConfig({
855
+ build: { manifest: true, minify: false },
856
+ plugins: [reactRouter()],
857
+ });
858
+ ` ,
859
+ "app/routes/_index.tsx" : js `
860
+ import { Link } from 'react-router'
861
+
862
+ export const unstable_clientMiddleware = [
863
+ ({ context }) => {
864
+ console.log('running index middleware')
865
+ },
866
+ ];
867
+
868
+ export default function Component() {
869
+ return (
870
+ <>
871
+ <h2 data-route>Index</h2>
872
+ <Link to="/about">Go to about</Link>
873
+ </>
874
+ );
875
+ }
876
+ ` ,
877
+ "app/routes/about.tsx" : js `
878
+ import { Link } from 'react-router'
879
+ export const unstable_clientMiddleware = [
880
+ ({ context }) => {
881
+ console.log('running about middleware')
882
+ },
883
+ ];
884
+
885
+ export default function Component() {
886
+ return (
887
+ <>
888
+ <h2 data-route>About</h2>
889
+ <Link to="/">Go to index</Link>
890
+ </>
891
+ );
892
+ }
893
+ ` ,
894
+ } ,
895
+ } ) ;
896
+
897
+ let appFixture = await createAppFixture ( fixture ) ;
898
+
899
+ let logs : string [ ] = [ ] ;
900
+ page . on ( "console" , ( msg ) => logs . push ( msg . text ( ) ) ) ;
901
+
902
+ let app = new PlaywrightFixture ( appFixture , page ) ;
903
+ await app . goto ( "/" ) ;
904
+
905
+ ( await page . $ ( 'a[href="/about"]' ) ) ?. click ( ) ;
906
+ await page . waitForSelector ( '[data-route]:has-text("About")' ) ;
907
+ expect ( logs ) . toEqual ( [ "running about middleware" ] ) ;
908
+ logs . splice ( 0 ) ;
909
+
910
+ ( await page . $ ( 'a[href="/"]' ) ) ?. click ( ) ;
911
+ await page . waitForSelector ( '[data-route]:has-text("Index")' ) ;
912
+ expect ( logs ) . toEqual ( [ "running index middleware" ] ) ;
913
+
914
+ appFixture . close ( ) ;
915
+ } ) ;
916
+
844
917
test ( "calls clientMiddleware before/after actions" , async ( { page } ) => {
845
918
let fixture = await createFixture ( {
846
919
files : {
@@ -1596,6 +1669,94 @@ test.describe("Middleware", () => {
1596
1669
appFixture . close ( ) ;
1597
1670
} ) ;
1598
1671
1672
+ test ( "calls middleware when no loaders exist on document, but not data requests" , async ( {
1673
+ page,
1674
+ } ) => {
1675
+ let oldConsoleLog = console . log ;
1676
+ let logs : any [ ] = [ ] ;
1677
+ console . log = ( ...args ) => logs . push ( args ) ;
1678
+
1679
+ let fixture = await createFixture ( {
1680
+ files : {
1681
+ "react-router.config.ts" : reactRouterConfig ( {
1682
+ middleware : true ,
1683
+ } ) ,
1684
+ "vite.config.ts" : js `
1685
+ import { defineConfig } from "vite";
1686
+ import { reactRouter } from "@react-router/dev/vite";
1687
+
1688
+ export default defineConfig({
1689
+ build: { manifest: true, minify: false },
1690
+ plugins: [reactRouter()],
1691
+ });
1692
+ ` ,
1693
+ "app/routes/parent.tsx" : js `
1694
+ import { Link, Outlet } from 'react-router'
1695
+
1696
+ export const unstable_middleware = [
1697
+ ({ request }) => {
1698
+ console.log('Running parent middleware', new URL(request.url).pathname)
1699
+ },
1700
+ ];
1701
+
1702
+ export default function Component() {
1703
+ return (
1704
+ <>
1705
+ <h2>Parent</h2>
1706
+ <Link to="/parent/a">Go to A</Link>
1707
+ <Link to="/parent/b">Go to B</Link>
1708
+ <Outlet/>
1709
+ </>
1710
+ );
1711
+ }
1712
+ ` ,
1713
+ "app/routes/parent.a.tsx" : js `
1714
+ export const unstable_middleware = [
1715
+ ({ request }) => {
1716
+ console.log('Running A middleware', new URL(request.url).pathname)
1717
+ },
1718
+ ];
1719
+
1720
+ export default function Component() {
1721
+ return <h3>A</h3>;
1722
+ }
1723
+ ` ,
1724
+ "app/routes/parent.b.tsx" : js `
1725
+ export const unstable_middleware = [
1726
+ ({ request }) => {
1727
+ console.log('Running B middleware', new URL(request.url).pathname)
1728
+ },
1729
+ ];
1730
+
1731
+ export default function Component() {
1732
+ return <h3>B</h3>;
1733
+ }
1734
+ ` ,
1735
+ } ,
1736
+ } ) ;
1737
+
1738
+ let appFixture = await createAppFixture ( fixture ) ;
1739
+
1740
+ let app = new PlaywrightFixture ( appFixture , page ) ;
1741
+ await app . goto ( "/parent/a" ) ;
1742
+ await page . waitForSelector ( 'h2:has-text("Parent")' ) ;
1743
+ await page . waitForSelector ( 'h3:has-text("A")' ) ;
1744
+ expect ( logs ) . toEqual ( [
1745
+ [ "Running parent middleware" , "/parent/a" ] ,
1746
+ [ "Running A middleware" , "/parent/a" ] ,
1747
+ ] ) ;
1748
+
1749
+ ( await page . $ ( 'a[href="/parent/b"]' ) ) ?. click ( ) ;
1750
+ await page . waitForSelector ( 'h3:has-text("B")' ) ;
1751
+ expect ( logs ) . toEqual ( [
1752
+ [ "Running parent middleware" , "/parent/a" ] ,
1753
+ [ "Running A middleware" , "/parent/a" ] ,
1754
+ ] ) ;
1755
+
1756
+ appFixture . close ( ) ;
1757
+ console . log = oldConsoleLog ;
1758
+ } ) ;
1759
+
1599
1760
test ( "calls middleware before/after actions" , async ( { page } ) => {
1600
1761
let fixture = await createFixture ( {
1601
1762
files : {
0 commit comments