_app.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import App, { AppContext } from "next/app";
  2. import { StoreProvider } from "easy-peasy";
  3. import getConfig from "next/config";
  4. import Router from "next/router";
  5. import decode from "jwt-decode";
  6. import cookie from "js-cookie";
  7. import Head from "next/head";
  8. import React from "react";
  9. import { initGA, logPageView , initSentry } from "../helpers/analytics";
  10. import { initializeStore } from "../store";
  11. import { TokenPayload } from "../types";
  12. const isProd = process.env.NODE_ENV === "production";
  13. const { publicRuntimeConfig } = getConfig();
  14. if (isProd) {
  15. initSentry();
  16. };
  17. // TODO: types
  18. class MyApp extends App<any> {
  19. static async getInitialProps({ Component, ctx }: AppContext) {
  20. const store = initializeStore();
  21. ctx.store = store;
  22. let pageProps = {};
  23. if (Component.getInitialProps) {
  24. pageProps = await Component.getInitialProps(ctx);
  25. }
  26. const token =
  27. ctx.req && (ctx.req as any).cookies && (ctx.req as any).cookies.token;
  28. const tokenPayload: TokenPayload = token ? decode(token) : null;
  29. if (tokenPayload) {
  30. store.dispatch.auth.add(tokenPayload);
  31. }
  32. return { pageProps, tokenPayload, initialState: store.getState() };
  33. }
  34. store: ReturnType<typeof initializeStore>;
  35. constructor(props) {
  36. super(props);
  37. this.store = initializeStore(props.initialState);
  38. }
  39. componentDidMount() {
  40. const { loading, auth } = this.store.dispatch;
  41. const token = cookie.get("token");
  42. if (token) {
  43. auth.renew().catch(() => {
  44. auth.logout();
  45. });
  46. }
  47. if (isProd) {
  48. initGA();
  49. logPageView();
  50. }
  51. Router.events.on("routeChangeStart", () => loading.show());
  52. Router.events.on("routeChangeComplete", () => {
  53. loading.hide();
  54. if (isProd) {
  55. logPageView();
  56. }
  57. });
  58. Router.events.on("routeChangeError", () => loading.hide());
  59. }
  60. render() {
  61. const { Component, pageProps } = this.props;
  62. return (
  63. <>
  64. <Head>
  65. <title>
  66. {publicRuntimeConfig.SITE_NAME} | Modern Open Source URL shortener.
  67. </title>
  68. </Head>
  69. <StoreProvider store={this.store}>
  70. <Component {...pageProps} />
  71. </StoreProvider>
  72. </>
  73. );
  74. }
  75. }
  76. export default MyApp;