Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
finwise-miniapp-fe
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ThinhNC
finwise-miniapp-fe
Commits
2ec6f4fd
Commit
2ec6f4fd
authored
Oct 15, 2026
by
ThinhNC
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(router): support standalone web basename and fallback api url on vercel
parent
98465e1f
Pipeline
#53708
passed with stage
in 35 seconds
Changes
6
Pipelines
2
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
94 additions
and
5 deletions
+94
-5
package.json
package.json
+1
-0
pnpm-lock.yaml
pnpm-lock.yaml
+3
-0
layout.tsx
src/components/layout.tsx
+1
-1
ZMPRouter.tsx
src/components/router/ZMPRouter.tsx
+80
-0
api-client.ts
src/lib/api-client.ts
+2
-1
vite.config.mts
vite.config.mts
+7
-3
No files found.
package.json
View file @
2ec6f4fd
...
...
@@ -29,6 +29,7 @@
"
react
"
:
"
^18.3.1
"
,
"
react-dom
"
:
"
^18.3.1
"
,
"
react-hook-form
"
:
"
^7.84.0
"
,
"
react-router-dom
"
:
"
^6.30.4
"
,
"
zmp-sdk
"
:
"
latest
"
,
"
zmp-ui
"
:
"
latest
"
,
"
zod
"
:
"
^4.4.3
"
,
...
...
pnpm-lock.yaml
View file @
2ec6f4fd
...
...
@@ -29,6 +29,9 @@ importers:
react-hook-form
:
specifier
:
^7.84.0
version
:
7.84.0(react@18.3.1)
react-router-dom
:
specifier
:
^6.30.4
version
:
6.30.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
zmp-sdk
:
specifier
:
latest
version
:
2.52.2(@babel/core@7.29.7)
...
...
src/components/layout.tsx
View file @
2ec6f4fd
...
...
@@ -4,9 +4,9 @@ import {
App
,
Route
,
SnackbarProvider
,
ZMPRouter
,
useNavigate
,
}
from
"zmp-ui"
;
import
{
ZMPRouter
}
from
"@/components/router/ZMPRouter"
;
import
{
QueryClientProvider
}
from
"@tanstack/react-query"
;
import
{
queryClient
}
from
"@/lib/query-client"
;
import
{
useAuthStore
,
GUEST_STORAGE_KEY
}
from
"@/stores/auth-store"
;
...
...
src/components/router/ZMPRouter.tsx
0 → 100644
View file @
2ec6f4fd
import
React
,
{
useCallback
,
useMemo
,
useRef
,
useState
}
from
"react"
;
import
{
BrowserRouter
,
MemoryRouter
}
from
"react-router-dom"
;
export
interface
AnimationRouterContextType
{
animate
:
boolean
;
direction
:
string
;
setAnimate
:
(
config
:
{
animate
?:
boolean
;
direction
?:
string
})
=>
void
;
pageScrollPosition
:
Record
<
string
,
number
>
;
updatePosition
:
(
key
:
string
,
position
:
number
)
=>
void
;
}
export
const
AnimationRouterContext
=
React
.
createContext
<
AnimationRouterContextType
|
undefined
>
(
undefined
);
export
interface
ZMPRouterProps
{
children
?:
React
.
ReactNode
;
memoryRouter
?:
boolean
;
}
const
PAGE_TRANSITION_FORWARD
=
"forward"
;
const
PAGE_TRANSITION_BACKWARD
=
"backward"
;
export
const
ZMPRouter
:
React
.
FC
<
ZMPRouterProps
>
=
(
props
)
=>
{
const
[
animate
,
setAnimate
]
=
useState
(
true
);
const
[
direction
,
setDirection
]
=
useState
(
PAGE_TRANSITION_FORWARD
);
const
pageScrollPosition
=
useRef
<
Record
<
string
,
number
>>
({});
const
{
children
,
memoryRouter
}
=
props
;
// Determine basepath safely:
// Inside Zalo webview, the path begins with `/zapps/<APP_ID>`.
// On Vercel / standalone web, use "" so all standard routes (/, /login, etc.) match.
const
win
=
typeof
window
!==
"undefined"
?
(
window
as
unknown
as
Record
<
string
,
unknown
>
)
:
null
;
let
basepath
=
(
win
?.
BASE_PATH
as
string
)
||
""
;
const
pathname
=
typeof
window
!==
"undefined"
?
window
.
location
.
pathname
:
""
;
const
appId
=
(
win
?.
APP_ID
as
string
)
||
""
;
if
(
pathname
.
startsWith
(
"/zapps/"
)
&&
appId
)
{
basepath
=
`/zapps/
${
appId
}
`
;
}
else
if
(
!
basepath
)
{
basepath
=
""
;
}
const
handleSetAnimate
=
useCallback
(
({
animate
:
ani
=
true
,
direction
:
dir
=
PAGE_TRANSITION_FORWARD
}:
{
animate
?:
boolean
;
direction
?:
string
})
=>
{
setAnimate
(
Boolean
(
ani
));
const
correctDirection
=
[
PAGE_TRANSITION_FORWARD
,
PAGE_TRANSITION_BACKWARD
].
includes
(
dir
)
?
dir
:
PAGE_TRANSITION_FORWARD
;
setDirection
(
correctDirection
);
},
[]
);
const
updateScrollPosition
=
(
key
:
string
,
position
:
number
)
=>
{
pageScrollPosition
.
current
[
key
]
=
position
;
};
const
contextValue
=
useMemo
(
()
=>
({
setAnimate
:
handleSetAnimate
,
animate
,
direction
,
pageScrollPosition
:
pageScrollPosition
.
current
,
updatePosition
:
updateScrollPosition
,
}),
[
animate
,
direction
,
handleSetAnimate
]
);
const
RouterComponent
=
memoryRouter
?
MemoryRouter
:
BrowserRouter
;
const
routerProps
=
memoryRouter
?
{
initialEntries
:
[
basepath
||
"/"
]
}
:
{};
return
(
<
AnimationRouterContext
.
Provider
value=
{
contextValue
}
>
<
RouterComponent
basename=
{
basepath
}
{
...
routerProps
}
>
{
children
}
</
RouterComponent
>
</
AnimationRouterContext
.
Provider
>
);
};
export
default
ZMPRouter
;
src/lib/api-client.ts
View file @
2ec6f4fd
...
...
@@ -2,7 +2,8 @@ import axios from "axios";
import
{
useAuthStore
}
from
"@/stores/auth-store"
;
import
{
safeStorage
}
from
"@/lib/storage"
;
export
const
API_BASE_URL
=
import
.
meta
.
env
.
VITE_API_URL
||
"http://localhost:7777/api/v1"
;
export
const
API_BASE_URL
=
import
.
meta
.
env
.
VITE_API_URL
||
"https://finwise-miniapp-be-wc86.onrender.com/api/v1"
;
const
apiBaseUrl
=
API_BASE_URL
;
// Create an Axios instance
...
...
vite.config.mts
View file @
2ec6f4fd
...
...
@@ -12,9 +12,13 @@ export default () => {
assetsInlineLimit: 0,
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
alias: [
{ find: "@", replacement: path.resolve(__dirname, "./src") },
{
find: /.*\/components\/router\/ZMPRouter(\.js)?$/,
replacement: path.resolve(__dirname, "./src/components/router/ZMPRouter.tsx"),
},
],
},
});
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment