Skip to content

Commit 7faad3e

Browse files
author
Andre Rabold
committed
Added React Router example configuration
1 parent cecacc6 commit 7faad3e

9 files changed

Lines changed: 178 additions & 19 deletions

File tree

handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ export const serve = async (event: APIGatewayEvent, context: Context): Promise<A
88
headers: {
99
"Content-Type": "text/html",
1010
},
11-
body: await render(),
11+
body: await render(event),
1212
};
1313
};

package-lock.json

Lines changed: 124 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"dependencies": {
2121
"react": "^16.14.0",
2222
"react-dom": "^16.14.0",
23+
"react-router-dom": "^5.2.0",
2324
"source-map-support": "^0.5.19"
2425
},
2526
"devDependencies": {
@@ -39,6 +40,7 @@
3940
"@types/prettier": "^2.1.6",
4041
"@types/react": "^16.14.2",
4142
"@types/react-dom": "^16.9.10",
43+
"@types/react-router-dom": "^5.1.7",
4244
"@types/serverless": "^1.78.20",
4345
"@types/source-map-support": "^0.5.3",
4446
"@types/webpack": "^4.41.26",

src/browser/App.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
import "./App.css";
22

33
import React from "react";
4+
import { Route, Switch } from "react-router-dom";
45

56
import useConfig from "../components/useConfig";
6-
import logo from "./logo.svg";
7+
import MainPage from "./pages/MainPage";
8+
import ErrorPage from "./pages/ErrorPage";
79

810
/**
911
* Our Web Application
1012
*/
1113
export default function App() {
12-
const config = useConfig();
14+
const { app } = useConfig();
1315
return (
14-
<div className="App">
15-
<header className="App-header">
16-
<img src={logo} className="App-logo" alt="logo" />
17-
<h1 className="App-title">Welcome to {config.app.TITLE}</h1>
18-
</header>
19-
<p className="App-intro">
20-
To get started, edit <code>src/browser/App.jsx</code> and save to reload.
21-
</p>
22-
</div>
16+
<Switch>
17+
<Route exact path="/">
18+
<MainPage />
19+
</Route>
20+
<Route>
21+
<ErrorPage />
22+
</Route>
23+
</Switch>
2324
);
2425
}

src/browser/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import "./index.css";
55
*/
66
import React from "react";
77
import { hydrate } from "react-dom";
8+
import { BrowserRouter } from "react-router-dom";
89

910
import ConfigContext from "../components/ConfigContext";
1011
import { Config } from "../server/config";
@@ -15,9 +16,13 @@ const config = (window as any).__CONFIG__ as Config;
1516
delete (window as any).__CONFIG__;
1617
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
1718

19+
const basename = config.app.URL.match(/^(?:https?:\/\/)?[^\/]+(\/?.+)?$/i)?.[1];
20+
1821
hydrate(
1922
<ConfigContext.Provider value={config}>
20-
<App />
23+
<BrowserRouter basename={basename}>
24+
<App />
25+
</BrowserRouter>
2126
</ConfigContext.Provider>,
2227
document.querySelector("#root"),
2328
);

src/browser/pages/ErrorPage.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import React from "react";
2+
3+
export default function ErrorPage() {
4+
return <div>404</div>;
5+
}

src/browser/pages/MainPage.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from "react";
2+
3+
import useConfig from "../../components/useConfig";
4+
import logo from "../logo.svg";
5+
6+
export default function MainPage() {
7+
const { app } = useConfig();
8+
return (
9+
<div className="App">
10+
<header className="App-header">
11+
<img src={logo} className="App-logo" alt="logo" />
12+
<h1 className="App-title">Welcome to {app.TITLE}</h1>
13+
</header>
14+
<p className="App-intro">
15+
To get started, edit <code>src/browser/App.jsx</code> and save to reload.
16+
</p>
17+
</div>
18+
);
19+
}

src/server/config.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ const config = {
2222
/** Theme is also loaded from the `manifest.json` */
2323
THEME_COLOR: manifest.theme_color,
2424
/** URL to our public API Gateway endpoint */
25-
URL: isLocal ? "http://localhost:3000" : String(process.env.APIGATEWAY_URL),
25+
URL: isLocal
26+
? `http://localhost:3000/${process.env.SERVERLESS_STAGE || "dev"}`
27+
: String(process.env.APIGATEWAY_URL),
2628
/** Where the bundled distribution files (`index.js`, `index.css`) are hosted */
2729
DIST_URL: isLocal ? "http://localhost:8080" : String(process.env.APP_DIST_URL),
2830
/** Where the contents of the `public` folder are hosted (might be the same as `config.app.DIST_URL`) */

src/server/render.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
* Server Side Rendering
33
*/
44
import React from "react";
5+
import { APIGatewayEvent } from "aws-lambda";
56
import { renderToString } from "react-dom/server";
7+
import { StaticRouter } from "react-router-dom";
68

79
import App from "../browser/App";
810
import ConfigContext from "../components/ConfigContext";
@@ -16,7 +18,7 @@ const isLocal = process.env.IS_LOCAL || process.env.IS_OFFLINE;
1618
/**
1719
* Server-side rendering
1820
*/
19-
export default async function render(): Promise<string> {
21+
export default async function render(event: APIGatewayEvent): Promise<string> {
2022
let stats: Stats = { main: "index.js", css: "index.css" };
2123
if (!isLocal) {
2224
try {
@@ -28,7 +30,9 @@ export default async function render(): Promise<string> {
2830

2931
const content = renderToString(
3032
<ConfigContext.Provider value={config}>
31-
<App />
33+
<StaticRouter basename={config.app.URL} location={event.path}>
34+
<App />
35+
</StaticRouter>
3236
</ConfigContext.Provider>,
3337
);
3438
return html({ stats, content, config });

0 commit comments

Comments
 (0)