Fix about and home ssr
Seto Elkahfi committed
Aug 7, 2023 at 23:34 UTC
48228a84d8fd5ec4b8cacab6fb0ed1c10daeffeb
8 files changed
+86
-37
server/server.tsx
+6
-10
@@ -27,23 +27,19 @@ server.get('*', (req, res, next) => {
27
return next();
28
}
29
30
- const promise = activeRoute.fetchInitialData
31
- ? activeRoute.fetchInitialData(req.path)
32
- : Promise.resolve();
30
+ activeRoute
31
+ .fetchInitialData(req.path, firebase)
32
+ .then((initialData) => {
33
34
- promise
35
- .then((data) => {
34
+ console.log('data', initialData);
35
36
const app = ReactDOMServer.renderToString(
37
<StaticRouter location={req.url}>
39
- <App firebase={firebase} />
38
+ <App initialData={initialData} />
39
</StaticRouter>
40
);
41
42
const indexFile = path.resolve('./build/index.html');
44
- const initialData = JSON.stringify(data);
45
-
46
- console.log('data', initialData);
43
console.log('req.path', req.path);
44
45
fs.readFile(indexFile, 'utf8', (err, data) => {
@@ -56,7 +52,7 @@ server.get('*', (req, res, next) => {
52
.replace(
53
'<div id="root"></div>',
54
`<div id="root">${app}</div>`
59
- )
55
+ )
56
.replace(
57
'<script id="initial-data"></script>',
58
`<script id="initial-data" type="application/json">
src/components/About.tsx
+19
-4
@@ -2,9 +2,11 @@ import React, { Component } from 'react';
2
import { FormattedMessage } from 'react-intl';
3
import Firebase from './Firebase';
4
import app from 'firebase/app';
5
+import { InitialData } from '../shared/routes';
6
7
type AboutProps = {
8
firebase: Firebase | null
9
+ initialData?: InitialData
10
}
11
12
type AboutState = {
@@ -20,13 +22,26 @@ class About extends Component<AboutProps, AboutState> {
22
constructor(props: AboutProps) {
23
super(props);
24
this.aboutRef = this.props.firebase?.aboutRef();
23
- this.state = {
24
- contentMain: "Loading ...",
25
- contentSkills: "Loading ...",
26
- updatedAt: "Loading ..."
25
+ if (this.props.initialData) {
26
+ console.log(this.props.initialData);
27
+ this.state = {
28
+ contentMain: this.props.initialData['data']['contentMain'],
29
+ contentSkills: this.props.initialData['data']['contentSkills'],
30
+ updatedAt: this.props.initialData['data']['updatedAt']
31
+ }
32
+ } else {
33
+ this.state = {
34
+ contentMain: "Loading ...",
35
+ contentSkills: "Loading ...",
36
+ updatedAt: "Loading ..."
37
+ }
38
}
39
}
40
+
41
componentDidMount() {
42
+ if (this.props.initialData)
43
+ return;
44
+
45
this.aboutRef?.on('value', (snapshot) => {
46
let items = snapshot?.val();
47
this.setState({
src/components/App.tsx
+8
-3
@@ -20,6 +20,7 @@ import messagesFr from "../translations/fr.json";
20
import messagesZh from "../translations/zh.json";
21
import messagesEs from "../translations/es.json";
22
import messagesJa from "../translations/ja.json";
23
+import { InitialData } from '../shared/routes';
24
25
addLocaleData([
26
...localeEn,
@@ -37,8 +38,9 @@ let i18nConfig = {
38
messages: messages_en
39
};
40
40
-type AppProps = {
41
- firebase: Firebase
41
+export type AppProps = {
42
+ firebase?: Firebase
43
+ initialData?: InitialData
44
}
45
46
type AppState = {
@@ -71,7 +73,10 @@ class App extends Component<AppProps, AppState> {
73
<IntlProvider locale={i18nConfig.language} messages={i18nConfig.messages}>
74
<FirebaseContext.Provider value={this.props.firebase}>
75
<Header onChangeLanguage={this.onChangeLanguage.bind(this)} />
74
- <Main />
76
+ <Main
77
+ firebase={this.props.firebase}
78
+ initialData={this.props.initialData}
79
+ />
80
<FooterLinks />
81
</FirebaseContext.Provider>
82
</IntlProvider >
src/components/Firebase/context.ts
+1
-1
@@ -1,6 +1,6 @@
1
import React from 'react';
2
import Firebase from './firebase';
3
4
-const FirebaseContext = React.createContext<Firebase | null>(null);
4
+const FirebaseContext = React.createContext<Firebase | undefined>(undefined);
5
6
export default FirebaseContext;
\ No newline at end of file
src/components/FooterLinks.tsx
-5
@@ -41,11 +41,6 @@ const FooterLinks = () => (
41
defaultMessage="About"
42
description="About link" />
43
</Link>
44
- <Link to='/cv' style={linkStyle}>
45
- <FormattedMessage id="header.cv"
46
- defaultMessage="CV"
47
- description="CV link" />
48
- </Link>
44
</p>
45
</div>
46
</footer>
src/components/Main.tsx
+11
-3
@@ -1,6 +1,7 @@
1
import React from 'react';
2
import { Switch, Route } from 'react-router-dom';
3
import routes from '../shared/routes';
4
+import { AppProps } from './App';
5
6
const mainStyle = {
7
marginTop: 20,
@@ -16,7 +17,11 @@ const contentStyle = {
17
backgroundColor: 'rgba(52, 52, 52, 0.6)'
18
}
19
19
-const Main = () => (
20
+const Main = (props: AppProps) => {
21
+
22
+ console.log('MAIN', props.initialData);
23
+
24
+ return (
25
<main style={mainStyle}>
26
<section className="py-5 text-center container">
27
<div className="row py-lg-5">
@@ -25,7 +30,10 @@ const Main = () => (
30
{
31
routes.map((route, index) => (
32
<Route key={index} exact={route.exact} path={route.path} >
28
- <route.component />
33
+ <route.component
34
+ firebase={props.firebase}
35
+ initialData={props.initialData}
36
+ />
37
</Route>
38
))
39
}
@@ -34,6 +42,6 @@ const Main = () => (
42
</div>
43
</section>
44
</main>
37
-);
45
+)};
46
47
export default Main;
\ No newline at end of file
src/shared/api.ts
+30
-1
@@ -1,4 +1,5 @@
1
import axios from "axios";
2
+import Firebase from "../components/Firebase";
3
4
axios.defaults.baseURL = 'https://api.musik88.com/api/v1/';
5
@@ -7,6 +8,34 @@ export const getCaraousel = () => {
8
.then(res => {
9
console.log(res);
10
const files = res.data.audio_files;
10
- return files;
11
+ const obj = {
12
+ path: '/',
13
+ data: files
14
+ };
15
+ return obj;
16
})
17
}
18
+
19
+export const getAbout = (path: string, firebase: Firebase) => {
20
+ return firebase
21
+ .aboutRef()
22
+ .once('value')
23
+ .then((snapshot) => {
24
+ return {
25
+ path: path,
26
+ data: snapshot.val()
27
+ }
28
+ });
29
+}
30
+
31
+export const getContact = (path: string, firebase: Firebase) => {
32
+ return firebase
33
+ .contactRef()
34
+ .once('value')
35
+ .then((snapshot) => {
36
+ return {
37
+ path: path,
38
+ data: snapshot.val()
39
+ }
40
+ });
41
+}
\ No newline at end of file
src/shared/routes.tsx
+11
-10
@@ -1,15 +1,21 @@
1
import Home from '../components/Home';
2
import About from '../components/About';
3
import React from 'react';
4
-import { getCaraousel } from './api';
4
+import { getAbout, getCaraousel, getContact } from './api';
5
import Contact from '../components/Contact';
6
import Cv from '../components/Cv';
7
+import Firebase from '../components/Firebase';
8
9
export interface Route {
10
path: string;
11
component: React.ComponentType<any>;
12
exact?: boolean;
12
- fetchInitialData?: (path?: string) => Promise<any>;
13
+ fetchInitialData: (path: string, firebase: Firebase) => Promise<InitialData>;
14
+}
15
+
16
+export type InitialData = {
17
+ data: any;
18
+ path: string;
19
}
20
21
// Desc: Routes for the application
@@ -18,22 +24,17 @@ const routes: Route[] = [
24
path: '/',
25
component: Home,
26
exact: true,
21
- fetchInitialData: () => getCaraousel()
27
+ fetchInitialData: (path, firebase) => getCaraousel()
28
},
29
{
30
path: '/about',
31
component: About,
26
- fetchInitialData: () => Promise.resolve()
27
- },
28
- {
29
- path: '/cv',
30
- component: Cv,
31
- fetchInitialData: () => Promise.resolve()
32
+ fetchInitialData: getAbout
33
},
34
{
35
path: '/contact',
36
component: Contact,
36
- fetchInitialData: () => Promise.resolve()
37
+ fetchInitialData: getContact
38
}
39
];
40