mirror of
https://github.com/documenso/documenso.git
synced 2026-08-23 14:52:23 +10:00
feat(remix): support serving app under a sub-path via NEXT_PUBLIC_BASE_PATH (#2824)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { formatPath } from '@documenso/lib/constants/app';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { type TDetectFieldsRequest, ZNormalizedFieldWithContextSchema } from './detect-fields.types';
|
||||
@@ -69,7 +70,7 @@ export const detectFields = async ({
|
||||
onError,
|
||||
signal,
|
||||
}: DetectFieldsOptions): Promise<void> => {
|
||||
const response = await fetch('/api/ai/detect-fields', {
|
||||
const response = await fetch(formatPath('/api/ai/detect-fields'), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { formatPath } from '@documenso/lib/constants/app';
|
||||
import { ZDetectedRecipientSchema } from '@documenso/lib/server-only/ai/envelope/detect-recipients/schema';
|
||||
import { z } from 'zod';
|
||||
|
||||
@@ -70,7 +71,7 @@ export const detectRecipients = async ({
|
||||
onError,
|
||||
signal,
|
||||
}: DetectRecipientsOptions): Promise<void> => {
|
||||
const response = await fetch('/api/ai/detect-recipients', {
|
||||
const response = await fetch(formatPath('/api/ai/detect-recipients'), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@@ -14,9 +14,22 @@ import { getLoadContext } from './hono/server/load-context.js';
|
||||
import server from './hono/server/router.js';
|
||||
import * as build from './index.js';
|
||||
|
||||
// Sub-path the app is served under (e.g. "/ESign"). Empty = root.
|
||||
// Must match the basePath used by the Hono router and the Vite `base`/RR
|
||||
// `basename` so that hashed asset URLs like `/ESign/assets/app-xxx.css`
|
||||
// resolve to files on disk at `build/client/assets/app-xxx.css`.
|
||||
const basePath = (process.env.NEXT_PUBLIC_BASE_PATH ?? '').replace(/\/$/, '');
|
||||
|
||||
server.use(
|
||||
serveStatic({
|
||||
root: 'build/client',
|
||||
rewriteRequestPath: (path) => {
|
||||
if (basePath && (path === basePath || path.startsWith(`${basePath}/`))) {
|
||||
const stripped = path.slice(basePath.length);
|
||||
return stripped === '' ? '/' : stripped;
|
||||
}
|
||||
return path;
|
||||
},
|
||||
onFound: (path, c) => {
|
||||
if (path.startsWith('build/client/assets')) {
|
||||
// Hard cache assets with hashed file names.
|
||||
|
||||
@@ -46,7 +46,9 @@ export interface HonoEnv {
|
||||
};
|
||||
}
|
||||
|
||||
const app = new Hono<HonoEnv>();
|
||||
const basePath = (env('NEXT_PUBLIC_BASE_PATH') ?? '').replace(/\/$/, '');
|
||||
|
||||
const app = new Hono<HonoEnv>().basePath(basePath || '/');
|
||||
|
||||
/**
|
||||
* Database-backed rate limiting for API routes.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { API_V2_BETA_URL, API_V2_URL } from '@documenso/lib/constants/app';
|
||||
import { API_V2_BETA_URL, API_V2_URL, formatPath } from '@documenso/lib/constants/app';
|
||||
import { AppError, genericErrorCodeToTrpcErrorCodeMap } from '@documenso/lib/errors/app-error';
|
||||
import { createTrpcContext } from '@documenso/trpc/server/context';
|
||||
import { appRouter } from '@documenso/trpc/server/router';
|
||||
@@ -11,8 +11,10 @@ type OpenApiTrpcServerHandlerOptions = {
|
||||
};
|
||||
|
||||
export const openApiTrpcServerHandler = async (c: Context, { isBeta }: OpenApiTrpcServerHandlerOptions) => {
|
||||
const endpoint = formatPath(isBeta ? API_V2_BETA_URL : API_V2_URL) as `/${string}`;
|
||||
|
||||
return createOpenApiFetchHandler<typeof appRouter>({
|
||||
endpoint: isBeta ? API_V2_BETA_URL : API_V2_URL,
|
||||
endpoint,
|
||||
router: appRouter,
|
||||
createContext: async () => createTrpcContext({ c, requestSource: 'apiV2' }),
|
||||
req: c.req.raw,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { formatPath } from '@documenso/lib/constants/app';
|
||||
import { createTrpcContext } from '@documenso/trpc/server/context';
|
||||
import { appRouter } from '@documenso/trpc/server/router';
|
||||
import { handleTrpcRouterError } from '@documenso/trpc/utils/trpc-error-handler';
|
||||
@@ -5,10 +6,14 @@ import { trpcServer } from '@hono/trpc-server';
|
||||
|
||||
/**
|
||||
* Trpc server for internal routes like /api/trpc/*
|
||||
*
|
||||
* `endpoint` must include the sub-path prefix (e.g. "/ESign") because the
|
||||
* @hono/trpc-server adapter slices the prefix off the full URL pathname to
|
||||
* compute the procedure name. Hono's `basePath` doesn't rewrite the URL.
|
||||
*/
|
||||
export const reactRouterTrpcServer = trpcServer({
|
||||
router: appRouter,
|
||||
endpoint: '/api/trpc',
|
||||
endpoint: formatPath('/api/trpc'),
|
||||
createContext: async (_, c) => createTrpcContext({ c, requestSource: 'app' }),
|
||||
onError: (opts) => handleTrpcRouterError(opts, 'trpc'),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user