Skip to content

Commit d26074e

Browse files
committed
feat: add base path to front end
- add docker build arg to set base path frontend is served under - set vite.config.ts base value based on docker build arg - update http variant request function to inject base path during calls to /api and /images - update how static assets are loaded from public folder to inject base path during vite build To use a base path build the docker image with --build-arg BASE_PATH=/hub/. All assets and api calls from the frontend will use that base path as prefix. The backend service is not using the base path, when using a proxy the base path has to be stripped.
1 parent 1c3e34c commit d26074e

File tree

11 files changed

+75
-33
lines changed

11 files changed

+75
-33
lines changed

Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
FROM node:20-alpine as frontend
2+
3+
# Set the base path for the frontend build
4+
# This can be overridden at build time with --build-arg BASE_PATH=<url>
5+
# Allows to build a frontend that can be served from a subpath, e.g. /hub/
6+
ARG BASE_PATH="/"
27
WORKDIR /build
38
COPY frontend ./frontend
9+
RUN echo "Building frontend with base path $BASE_PATH"
410
RUN cd frontend && yarn install --network-timeout 3000000 && yarn build:http
11+
RUN cat frontend/dist/index.html
512

613
FROM golang:1.24 as builder
714

frontend/platform_specific/http/src/utils/request.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
import { getAuthToken } from "src/lib/auth";
22
import { ErrorResponse } from "src/types";
33

4+
const BASE_URL = import.meta.env.BASE_URL;
5+
const PREFIXES = ["/api", "/images"];
6+
7+
function startsWithPrefix(path: string, prefixes: string[]): boolean {
8+
return prefixes.some((prefix) => path.startsWith(prefix));
9+
}
10+
411
export const request = async <T>(
512
...args: Parameters<typeof fetch>
613
): Promise<T | undefined> => {
14+
if (
15+
BASE_URL !== "/" &&
16+
typeof args[0] === "string" &&
17+
startsWithPrefix(args[0], PREFIXES)
18+
) {
19+
args[0] = BASE_URL + args[0].slice(1);
20+
}
21+
722
const token = getAuthToken();
823
if (token) {
924
if (!args[1]) {

frontend/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import routes from "src/routes.tsx";
1313
import { isHttpMode } from "src/utils/isHttpMode";
1414

1515
const createRouterFunc = isHttpMode() ? createBrowserRouter : createHashRouter;
16-
const router = createRouterFunc(routes);
16+
const router = createRouterFunc(routes, { basename: import.meta.env.BASE_URL });
1717

1818
function App() {
1919
const { data: info } = useInfo();

frontend/src/components/connections/AlbyConnectionCard.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ import { useAlbyMe } from "src/hooks/useAlbyMe";
4646
import { LinkStatus, useLinkAccount } from "src/hooks/useLinkAccount";
4747
import { App, BudgetRenewalType } from "src/types";
4848

49+
import AlbyAccountDarkSVG from "public/images/illustrations/alby-account-dark.svg";
50+
import AlbyAccountLightSVG from "public/images/illustrations/alby-account-light.svg";
51+
4952
function AlbyConnectionCard({ connection }: { connection?: App }) {
5053
const { data: albyMe } = useAlbyMe();
5154
const { loading, linkStatus, loadingLinkStatus, linkAccount } =
@@ -109,11 +112,11 @@ function AlbyConnectionCard({ connection }: { connection?: App }) {
109112
every app you access through your Alby Account will
110113
handle payments via the Hub.
111114
<img
112-
src="/images/illustrations/alby-account-dark.svg"
115+
src={AlbyAccountDarkSVG}
113116
className="w-full hidden dark:block"
114117
/>
115118
<img
116-
src="/images/illustrations/alby-account-light.svg"
119+
src={AlbyAccountLightSVG}
117120
className="w-full dark:hidden"
118121
/>
119122
You can add a budget that will restrict how much can be

frontend/src/components/layouts/TwoColumnFullScreenLayout.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ import { AlbyHubLogo } from "src/components/icons/AlbyHubLogo";
55
import { Button } from "src/components/ui/button.tsx";
66
import { useInfo } from "src/hooks/useInfo";
77

8+
import AntonopoulosSVG from "public/images/quotes/antonopoulos.svg";
9+
import BackSVG from "public/images/quotes/back.svg";
10+
import FinneySVG from "public/images/quotes/finney.svg";
11+
import HayekSVG from "public/images/quotes/hayek.svg";
12+
import NakamotoSVG from "public/images/quotes/nakamoto.svg";
13+
import ObamaSVG from "public/images/quotes/obama.svg";
14+
import RolandSVG from "public/images/quotes/roland.svg";
15+
import WilsonSVG from "public/images/quotes/wilson.svg";
16+
817
const quotes = [
918
{
1019
content: `This isn't about nation-states anymore. This isn't about who adopts
@@ -13,42 +22,42 @@ const quotes = [
1322
largest economy. It is the first transnational economy, and it needs a
1423
transnational currency.`,
1524
author: "Andreas M. Antonopoulos",
16-
imageUrl: "/images/quotes/antonopoulos.svg",
25+
imageUrl: AntonopoulosSVG,
1726
},
1827
{
1928
content: `It might make sense just to get some in case it catches on. If enough people think the same way, that becomes a self fulfilling prophecy. Once it gets bootstrapped, there are so many applications if you could effortlessly pay a few cents to a website as easily as dropping coins in a vending machine.`,
2029
author: "Satoshi Nakamoto",
21-
imageUrl: "/images/quotes/nakamoto.svg",
30+
imageUrl: NakamotoSVG,
2231
},
2332
{
2433
content: `Since we're all rich with bitcoins, or we will be once they're worth a million dollars like everyone expects, we ought to put some of this unearned wealth to good use.`,
2534
author: "Hal Finney",
26-
imageUrl: "/images/quotes/finney.svg",
35+
imageUrl: FinneySVG,
2736
},
2837
{
2938
content: `I don't believe we shall ever have a good money again before we take the thing out of the hands of government, that is, we can't take it violently out of the hands of government, all we can do is by some sly roundabout way introduce something that they can't stop.`,
3039
author: "Friedrich August von Hayek",
31-
imageUrl: "/images/quotes/hayek.svg",
40+
imageUrl: HayekSVG,
3241
},
3342
{
3443
content: `Bitcoin is what they fear it is.`,
3544
author: "Cody Wilson",
36-
imageUrl: "/images/quotes/wilson.svg",
45+
imageUrl: WilsonSVG,
3746
},
3847
{
3948
content: `If in fact you can't crack that at all, government can't get in then —everybody's walking around with a Swiss bank account in their pocket.`,
4049
author: "Barack Obama",
41-
imageUrl: "/images/quotes/obama.svg",
50+
imageUrl: ObamaSVG,
4251
},
4352
{
4453
content: `Bitcoin is the new wonder of the world, more work and human ingenuity, than went into the great pyramids of Egypt. The biggest computation ever done, a digital monument, a verifiable artefact of digital gold - the foundation of a new digital age.`,
4554
author: "Adam Back",
46-
imageUrl: "/images/quotes/back.svg",
55+
imageUrl: BackSVG,
4756
},
4857
{
4958
content: `We who choose Bitcoin, are pioneers of a new world. A world filled with freedom, hope and peace.`,
5059
author: "Roland",
51-
imageUrl: "/images/quotes/roland.svg",
60+
imageUrl: RolandSVG,
5261
},
5362
];
5463

frontend/src/screens/channels/IncreaseIncomingCapacity.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ import {
4444
RecommendedChannelPeer,
4545
} from "src/types";
4646

47+
import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg";
48+
import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg";
49+
4750
function getPeerKey(peer: RecommendedChannelPeer) {
4851
return JSON.stringify(peer);
4952
}
@@ -229,13 +232,10 @@ function NewChannelInternal({
229232
/>
230233
<div className="md:max-w-md max-w-full flex flex-col gap-5 flex-1">
231234
<img
232-
src="/images/illustrations/lightning-network-dark.svg"
235+
src={LightningNetworkDarkSVG}
233236
className="w-full hidden dark:block"
234237
/>
235-
<img
236-
src="/images/illustrations/lightning-network-light.svg"
237-
className="w-full dark:hidden"
238-
/>
238+
<img src={LightningNetworkLightSVG} className="w-full dark:hidden" />
239239
<p className="text-muted-foreground">
240240
Alby Hub works with selected service providers (LSPs) which provide
241241
the best network connectivity and liquidity to receive payments.{" "}

frontend/src/screens/channels/IncreaseOutgoingCapacity.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ import {
4747
} from "src/types";
4848
import { request } from "src/utils/request";
4949

50+
import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg";
51+
import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg";
52+
5053
function getPeerKey(peer: RecommendedChannelPeer) {
5154
return JSON.stringify(peer);
5255
}
@@ -200,13 +203,10 @@ function NewChannelInternal({ network }: { network: Network }) {
200203
/>
201204
<div className="md:max-w-md max-w-full flex flex-col gap-5 flex-1">
202205
<img
203-
src="/images/illustrations/lightning-network-dark.svg"
206+
src={LightningNetworkDarkSVG}
204207
className="w-full hidden dark:block"
205208
/>
206-
<img
207-
src="/images/illustrations/lightning-network-light.svg"
208-
className="w-full dark:hidden"
209-
/>
209+
<img src={LightningNetworkLightSVG} className="w-full dark:hidden" />
210210
<p className="text-muted-foreground">
211211
Open a channel with on-chain funds. Both parties are free to close the
212212
channel at any time. However, by keeping more funds on your side of

frontend/src/screens/channels/auto/AutoChannel.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import { MempoolAlert } from "src/components/MempoolAlert";
2020
import { PayLightningInvoice } from "src/components/PayLightningInvoice";
2121
import { ChannelPublicPrivateAlert } from "src/components/channels/ChannelPublicPrivateAlert";
2222

23+
import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg";
24+
import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg";
25+
2326
export function AutoChannel() {
2427
const { data: info } = useInfo();
2528
const { data: channels } = useChannels(true);
@@ -134,11 +137,11 @@ export function AutoChannel() {
134137
<>
135138
<div className="flex flex-col gap-6 max-w-md text-muted-foreground">
136139
<img
137-
src="/images/illustrations/lightning-network-dark.svg"
140+
src={LightningNetworkDarkSVG}
138141
className="w-full hidden dark:block"
139142
/>
140143
<img
141-
src="/images/illustrations/lightning-network-light.svg"
144+
src={LightningNetworkLightSVG}
142145
className="w-full dark:hidden"
143146
/>
144147

frontend/src/screens/channels/first/FirstChannel.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ import { PayLightningInvoice } from "src/components/PayLightningInvoice";
2323
import { Table, TableBody, TableCell, TableRow } from "src/components/ui/table";
2424
import { ALBY_MIN_HOSTED_BALANCE_FOR_FIRST_CHANNEL } from "src/constants";
2525

26+
import LightningNetworkDarkSVG from "public/images/illustrations/lightning-network-dark.svg";
27+
import LightningNetworkLightSVG from "public/images/illustrations/lightning-network-light.svg";
28+
2629
export function FirstChannel() {
2730
const { data: info } = useInfo();
2831
const { data: channels } = useChannels(true);
@@ -167,11 +170,11 @@ export function FirstChannel() {
167170
<>
168171
<div className="flex flex-col gap-6 max-w-md text-muted-foreground">
169172
<img
170-
src="/images/illustrations/lightning-network-dark.svg"
173+
src={LightningNetworkDarkSVG}
171174
className="w-full hidden dark:block"
172175
/>
173176
<img
174-
src="/images/illustrations/lightning-network-light.svg"
177+
src={LightningNetworkLightSVG}
175178
className="w-full dark:hidden"
176179
/>
177180
{canPayForFirstChannel ? (

frontend/src/screens/subwallets/SubwalletIntro.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import ExternalLink from "src/components/ExternalLink";
1111
import ResponsiveButton from "src/components/ResponsiveButton";
1212
import { Button } from "src/components/ui/button";
1313

14+
import SubWalletDarkSVG from "public/images/illustrations/sub-wallet-dark.svg";
15+
import SubWalletLightSVG from "public/images/illustrations/sub-wallet-light.svg";
16+
1417
export function SubwalletIntro() {
1518
return (
1619
<div className="grid gap-4">
@@ -33,14 +36,8 @@ export function SubwalletIntro() {
3336
<div>
3437
<div className="flex flex-col gap-6 max-w-screen-md">
3538
<div className="mb-2">
36-
<img
37-
src="/images/illustrations/sub-wallet-dark.svg"
38-
className="w-72 hidden dark:block"
39-
/>
40-
<img
41-
src="/images/illustrations/sub-wallet-light.svg"
42-
className="w-72 dark:hidden"
43-
/>
39+
<img src={SubWalletDarkSVG} className="w-72 hidden dark:block" />
40+
<img src={SubWalletLightSVG} className="w-72 dark:hidden" />
4441
</div>
4542
<div>
4643
<div className="flex flex-row gap-3">

frontend/vite.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ export default defineConfig(({ command }) => ({
6464
alias: {
6565
src: path.resolve(__dirname, "./src"),
6666
wailsjs: path.resolve(__dirname, "./wailsjs"),
67+
// used to refrence public assets when importing images or other
68+
// assets from the public folder
69+
// this is necessary to inject the base path during build
70+
public: "",
6771
},
6872
},
6973
build: {
@@ -75,6 +79,7 @@ export default defineConfig(({ command }) => ({
7579
cspNonce: "DEVELOPMENT",
7680
}
7781
: undefined,
82+
base: process.env.BASE_PATH || "/",
7883
}));
7984

8085
const DEVELOPMENT_NONCE = "'nonce-DEVELOPMENT'";

0 commit comments

Comments
 (0)