Skip to content

apivideo/udemy-clone-next-typescript

Repository files navigation

api.video Logo

Udemy clone with api.video + Next.js + Typescript πŸ‘©β€πŸŽ“

Twitter Badge Pull Requests Badge

An open-source example application that allows users to create a learning plaform like Udemy with api.video

Go to the demo ▢️

Table of Contents

  1. About The Project
  2. Getting Started

About The Project

api.video:

We'll recreate the video bookmark feature from Udemy and show a video progress using api.video's Node.js client and player SDK

  • @api.video/nodejs-client. - api.video's Node.js is a lightweight client built in TypeScript that streamlines the coding process. Chunking files is handled for you, as is pagination and refreshing your tokens.

  • @api.video/player-sdk - SDK to control and interact with the api.video HTML5 Player

Getting Started

Step 1. Clone

First we need to clone the project

git clone git@github.com:apivideo/udemy-clone-next-typescript.git
cd udemy-clone-next-typescript

# run the development server
npm run dev
# or
yarn dev

Step 2. Create an account

All you need to set this up is a api.video account. You can sign up for free. You can use our services in sandbox environment but the videos you upload will last 24 hours.

Once you signed up, you will have a sandbox API Key available on the home page.

Step 3. Set Up Environment Variables

In order to see your videos by default, all you have to do is to use your API Key. You need to create a environment variable at the root of the project.

touch .env.development

Then edit the file like API_KEY should be your API_KEY available on the dashboard

API_KEY = YOUR_API_KEY;

Project Configurations

Configuration styled-components

Since 12.1, Next.js added support to the Next.js Compiler for styled-components, update your next.config.js file:

// next.config.js
module.exports = {
	compiler: {
		styledComponents: true,
  }
},

Create a custom _document.js file

To render our styled-components at the server-side, we need to override _document.js. For this, create a _document.js file under the pages folder and add the following content into it. We will use also use the google font Roboto.

import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components';

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }
  render() {
    return (
      <Html>
        <Head>
          <link
            href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,400&display=swap"
            rel="stylesheet"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

Typescript configuration

In your root folder, create a tsconfig.json file and copy the following TS configuration. I like to use absolute imports with @ throughout the project.

// tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "baseUrl": ".",
    "allowSyntheticDefaultImports": true,
    "types": ["@typescript-eslint/eslint-plugin"],
    "paths": {
      "@public/*": ["public/*"],
      "@components/*": ["src/components/*"],
      "@utils/*": ["src/utils/*"]
    },
    "incremental": true
  },
  "include": ["next-env.d.ts", "@types/*.d.ts", "**/**/*.ts", "**/**/*.tsx"],
  "exclude": ["node_modules"]
}

Configuring next.config.js for SVG imports

We are using some SVG imports in the project, so to make it work we need to install @svgr/webpack and add a little configuration in our next.config.js file.

npm i @svgr/webpack

Copy this configuration to your next.config.js file:

// next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  compiler: {
    styledComponents: true,
  },
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/i,
      issuer: /\.[jt]sx?$/,
      use: ['@svgr/webpack'],
    });

    return config;
  },
};

module.exports = nextConfig;

About

Rebuilding Udemy with api.video, Next.js and Typescript πŸŽ“

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages