WIp
Seto Elkahfi committed
Aug 3, 2023 at 11:35 UTC
24bc90a0acf7fa01e92bb4160db4158b77d0788a
9 files changed
+104
-66
README.md
+3
@@ -7,6 +7,9 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo
7
3. Run `npm run build` to build the project.
8
4. RUn `firebase deploy` to deploy the new build.
9
10
+## SSR
11
+
12
+https://ui.dev/react-router-server-rendering
13
14
## Available Scripts
15
public/index.html
+1
@@ -14,6 +14,7 @@ Just like me, you know nothing :)
14
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
15
<script src="https://cdn.jsdelivr.net/jquery.supersized/3.2.7/core/js/supersized.core.3.2.1.min.js"></script>
16
<script type="text/javascript">$(function(e){e.supersized({start_slide:0,new_window:1,image_protect:1,min_width:0,min_height:0,vertical_center:1,horizontal_center:1,fit_always:0,fit_portrait:1,fit_landscape:0,slides:[{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/kazvan-1.jpg",title:"Image Credit: Maria Kazvan"},{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/kazvan-3.jpg",title:"Image Credit: Maria Kazvan"},{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/wojno-1.jpg",title:"Image Credit: Colin Wojno"},{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/wojno-2.jpg",title:"Image Credit: Colin Wojno"},{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/wojno-3.jpg",title:"Image Credit: Colin Wojno"}]})});</script>
17
+ <script id="initial-data"></script>
18
</head>
19
<body>
20
<noscript>You need to enable JavaScript to run this app.</noscript>
server/server.tsx
+43
-17
@@ -5,7 +5,7 @@ import App from '../src/components/App'
5
import path from 'path';
6
import fs from 'fs';
7
import { StaticRouter, matchPath } from 'react-router-dom';
8
-import routes from '../shared/routes';
8
+import routes from '../src/shared/routes';
9
import Firebase from '../src/components/Firebase';
10
import firebaseInstance from '../src/components/Firebase/config';
11
@@ -19,28 +19,54 @@ server.get('*', (req, res, next) => {
19
20
const activeRoute = routes.find((route) =>
21
matchPath(route.path, req.url)
22
- ) || {}
22
+ )
23
24
const firebase = new Firebase('en', firebaseInstance.database());
25
26
- const app = ReactDOMServer.renderToString(
27
- <StaticRouter location={req.url}>
28
- <App firebase={firebase} />
29
- </StaticRouter>
30
- );
26
+ if (!activeRoute) {
27
+ return next();
28
+ }
29
32
- const indexFile = path.resolve('./build/index.html');
30
+ const promise = activeRoute.fetchInitialData
31
+ ? activeRoute.fetchInitialData(req.path)
32
+ : Promise.resolve();
33
34
- fs.readFile(indexFile, 'utf8', (err, data) => {
35
- if (err) {
36
- console.error('Something went wrong:', err);
37
- return res.status(500).send('Oops, better luck next time!');
38
- }
34
+ promise
35
+ .then((data) => {
36
40
- return res.send(
41
- data.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
42
- );
43
- });
37
+ const app = ReactDOMServer.renderToString(
38
+ <StaticRouter location={req.url}>
39
+ <App firebase={firebase} />
40
+ </StaticRouter>
41
+ );
42
+
43
+ const indexFile = path.resolve('./build/index.html');
44
+ const initialData = JSON.stringify(data);
45
+
46
+ console.log('data', initialData);
47
+ console.log('req.path', req.path);
48
+
49
+ fs.readFile(indexFile, 'utf8', (err, data) => {
50
+ if (err) {
51
+ console.error('Something went wrong:', err);
52
+ return res.status(500).send('Oops, better luck next time!');
53
+ }
54
+ return res.send(
55
+ data
56
+ .replace(
57
+ '<div id="root"></div>',
58
+ `<div id="root">${app}</div>`
59
+ )
60
+ .replace(
61
+ '<script id="initial-data"></script>',
62
+ `<script id="initial-data" type="application/json">
63
+ window.__DATA__=${initialData}
64
+ </script>`
65
+ )
66
+ );
67
+ });
68
+ })
69
+ .catch(next);
70
});
71
72
server.listen(3002, () => {
shared/routes.tsx
deleted
-16
@@ -1,16 +0,0 @@
1
-import Home from '../src/components/Home';
2
-import About from '../src/components/About';
3
-
4
-// Desc: Routes for the application
5
-const routes = [
6
- {
7
- path: '/',
8
- component: Home,
9
- },
10
- {
11
- path: '/about',
12
- component: About,
13
- }
14
-];
15
-
16
-export default routes;
\ No newline at end of file
src/components/App.tsx
+2
-4
@@ -47,8 +47,6 @@ type AppState = {
47
48
class App extends Component<AppProps, AppState> {
49
50
- firebase: Firebase | null = null;
51
-
50
onChangeLanguage(language: string) {
51
switch (language) {
52
case 'se': i18nConfig.messages = messages_sv; break;
@@ -63,8 +61,8 @@ class App extends Component<AppProps, AppState> {
61
}
62
i18nConfig.language = language;
63
this.setState({ language: language })
66
- if (this.firebase) {
67
- this.firebase.setLanguage(language)
64
+ if (this.props.firebase) {
65
+ this.props.firebase.setLanguage(language)
66
}
67
}
68
src/components/Firebase/firebase.ts
+4
-3
@@ -7,15 +7,16 @@ class Firebase {
7
language!: string;
8
9
public onLanguageChangedCallback: (() => void) | null = null
10
- private static instace: Firebase
10
+ private static instance: Firebase
11
12
constructor(language: string, db: app.database.Database) {
13
14
- if (Firebase.instace)
15
- return Firebase.instace
14
+ if (Firebase.instance)
15
+ return Firebase.instance
16
17
this.db = db;
18
this.language = language;
19
+ Firebase.instance = this;
20
}
21
22
setLanguage(language: string) {
src/components/Main.tsx
+8
-26
@@ -1,11 +1,7 @@
1
import React from 'react';
2
import { Switch, Route } from 'react-router-dom';
3
-import Home from './Home';
4
-import About from './About';
5
-import Cv from './Cv';
6
-import Contact from './Contact';
3
import { FirebaseContext } from './Firebase';
8
-import AudioPlayer from './AudioPlayer';
4
+import routes from '../shared/routes';
5
6
const mainStyle = {
7
marginTop: 20,
@@ -27,27 +23,13 @@ const Main = () => (
23
<div className="row py-lg-5">
24
<div className="col-lg-6 col-md-8 mx-auto" style={contentStyle}>
25
<Switch>
30
- <Route exact path='/'>
31
- <FirebaseContext.Consumer>
32
- {firebase => <Home firebase={firebase} />}
33
- </FirebaseContext.Consumer>
34
- </Route>
35
- <Route path='/about'>
36
- <FirebaseContext.Consumer>
37
- {firebase => <About firebase={firebase} />}
38
- </FirebaseContext.Consumer>
39
- </Route>
40
- <Route path='/cv'>
41
- <FirebaseContext.Consumer>
42
- {firebase => <Cv firebase={firebase} />}
43
- </FirebaseContext.Consumer>
44
- </Route>
45
-
46
- <Route path='/contact'>
47
- <FirebaseContext.Consumer>
48
- {firebase => <Contact firebase={firebase} />}
49
- </FirebaseContext.Consumer>
50
- </Route>
26
+ {
27
+ routes.map((route, index) => (
28
+ <Route key={index} path={route.path}>
29
+ <route.component />
30
+ </Route>
31
+ ))
32
+ }
33
</Switch>
34
</div>
35
</div>
src/shared/api.ts
new
+12
@@ -0,0 +1,12 @@
1
+import axios from "axios";
2
+
3
+axios.defaults.baseURL = 'https://api.musik88.com/api/v1/';
4
+
5
+export const getCaraousel = () => {
6
+ return axios.get(`/carousel`)
7
+ .then(res => {
8
+ console.log(res);
9
+ const files = res.data.audio_files;
10
+ return files;
11
+ })
12
+}
src/shared/routes.tsx
new
+31
@@ -0,0 +1,31 @@
1
+import Home from '../components/Home';
2
+import About from '../components/About';
3
+import React from 'react';
4
+import { getCaraousel } from './api';
5
+
6
+export interface Route {
7
+ path: string;
8
+ component: React.ComponentType<any>;
9
+ fetchInitialData?: (path?: string) => Promise<any>;
10
+}
11
+
12
+// Desc: Routes for the application
13
+const routes: Route[] = [
14
+ {
15
+ path: '/',
16
+ component: Home,
17
+ fetchInitialData: (path = '') => getCaraousel()
18
+ },
19
+ {
20
+ path: '/about',
21
+ component: About,
22
+ fetchInitialData: (path = '') => Promise.resolve()
23
+ },
24
+ {
25
+ path: '/cv',
26
+ component: About,
27
+ fetchInitialData: (path = '') => Promise.resolve()
28
+ }
29
+];
30
+
31
+export default routes;
\ No newline at end of file