An open-source example application that allows users to create a learning plaform like Udemy with api.video
Go to the demo
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
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
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.
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;
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;