├── .env-sample ├── src ├── db │ ├── sql.zip │ ├── seed.ts │ ├── db.ts │ └── courses.json ├── routes │ ├── index.ts │ ├── CourseRoutes.ts │ └── LessonRoutes.ts ├── repositories │ ├── CoursesRepo.ts │ └── LessonsRepo.ts ├── handlers │ └── errorHandler.ts ├── middlewares │ └── rateLimit.ts ├── models │ ├── Lesson.ts │ └── Course.ts ├── controllers │ ├── CoursesCtrl.ts │ └── LessonsCtrl.ts ├── validators │ └── lessonValidator.ts └── index.ts ├── .vscode ├── extensions.json └── settings.json ├── .editorconfig ├── ecosystem.config.ts ├── tsconfig.json ├── server.ts ├── tslint.json ├── .gitignore ├── package.json ├── CONTRIBUTING.md ├── postman_collection └── rest-api-node-typescript.postman_collection.json └── Readme.MD /.env-sample: -------------------------------------------------------------------------------- 1 | DB_URL=localhost 2 | PORT=3000 3 | NODE_ENV=development 4 | RATE_LIMIT_REQUEST: 10 5 | -------------------------------------------------------------------------------- /src/db/sql.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmanikiran/rest-api-node-typescript/HEAD/src/db/sql.zip -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "christian-kohler.npm-intellisense", 4 | "christian-kohler.path-intellisense", 5 | "eg2.tslint", 6 | "esbenp.prettier-vscode", 7 | "wix.vscode-import-cost" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Tab indentation 7 | [*] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | -------------------------------------------------------------------------------- /ecosystem.config.ts: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apps: [ 3 | { 4 | name: "API", 5 | script: "server.js", 6 | instances: 2, 7 | watch: true, 8 | autostart: true, 9 | max_memory_restart: "1G", 10 | env: { NODE_ENV: "development" }, 11 | env_production: { NODE_ENV: "development" }, 12 | }, 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /src/routes/index.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'express'; 2 | import courseRouter from './CourseRoutes'; 3 | import lessonRouter from './LessonRoutes'; 4 | 5 | export default class Routes { 6 | 7 | constructor(app: Application) { 8 | // course reoutes 9 | app.use('/api/courses', courseRouter); 10 | // lesson routes 11 | app.use('/api/lessons', lessonRouter); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.formatOnPaste": true, 4 | "prettier.singleQuote": true, 5 | "prettier.trailingComma": "all", 6 | "editor.fontFamily": "Fira Code, Consolas, 'Courier New', monospace", 7 | "files.exclude": { 8 | "**/*.js": { 9 | "when": "$(basename).ts" 10 | }, 11 | "**/*.js.map": { 12 | "when": "$(basename)" 13 | } 14 | }, 15 | "prettier.tslintIntegration": true 16 | } 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "noImplicitAny": false, 6 | "sourceMap": true, 7 | "strict": true, 8 | "allowJs": false 9 | }, 10 | "files.exclude": { 11 | "**/.git": true, 12 | "**/.svn": true, 13 | "**/.hg": true, 14 | "**/.DS_Store": true, 15 | "**/node_modules": true, 16 | "**/*.js": { 17 | "when": "$(basename).ts" 18 | }, 19 | "**/*.js.map": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/routes/CourseRoutes.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import CoursesCtrl from '../controllers/CoursesCtrl'; 3 | 4 | class CourseRoutes { 5 | router = Router(); 6 | coursesCtrl = new CoursesCtrl(); 7 | 8 | constructor() { 9 | this.intializeRoutes(); 10 | } 11 | intializeRoutes() { 12 | this.router.route('/').get(this.coursesCtrl.getAllCourses); 13 | this.router.route('/:id').get(this.coursesCtrl.getCourseDetails); 14 | } 15 | } 16 | export default new CourseRoutes().router; 17 | -------------------------------------------------------------------------------- /src/repositories/CoursesRepo.ts: -------------------------------------------------------------------------------- 1 | import { Course } from '../models/Course'; 2 | import { Lesson } from '../models/Lesson'; 3 | 4 | class CourseRepo { 5 | constructor() { } 6 | 7 | getAllCourses(options) { 8 | return Course.findAll(options); 9 | } 10 | 11 | getById(courseId) { 12 | return Course.findByPk(courseId, { 13 | include: [ 14 | { 15 | model: Lesson, 16 | as: 'lessons' 17 | }, 18 | ], 19 | }); 20 | } 21 | } 22 | 23 | export default new CourseRepo(); 24 | -------------------------------------------------------------------------------- /server.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | dotenv.config(); 3 | import * as express from 'express'; 4 | import { Application } from 'express'; 5 | 6 | import Server from './src/index'; 7 | 8 | const app: Application = express(); 9 | const server: Server = new Server(app); 10 | const port: number = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000; 11 | 12 | app.listen(port, 'localhost', function () { 13 | console.info(`Server running on : http://localhost:${port}`); 14 | }).on('error', (err: any) => { 15 | if (err.code === 'EADDRINUSE') { 16 | console.log('server startup error: address already in use'); 17 | } else { 18 | console.log(err); 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /src/db/seed.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | import * as path from 'path'; 3 | dotenv.config({ path: path.join(__dirname + '../../../.env') }); 4 | 5 | import { Course } from '../models/Course'; 6 | import { Lesson } from '../models/Lesson'; 7 | const courses: object[] = require('./courses.json'); 8 | 9 | 10 | Course.sync({ force: true }) 11 | .then(() => Lesson.sync({ force: true })) 12 | .then(() => console.log('Database cleaned')) 13 | .then(() => Course.bulkCreate(courses, { include: [{ model: Lesson, as: 'lessons' }] })) 14 | .then(() => { 15 | console.log('############# seeding completed #################'); 16 | process.exit(); 17 | }) 18 | .catch(console.error); 19 | -------------------------------------------------------------------------------- /src/repositories/LessonsRepo.ts: -------------------------------------------------------------------------------- 1 | import { Lesson } from '../models/Lesson'; 2 | 3 | class LessonRepo { 4 | constructor() { } 5 | 6 | getAllLessons(options) { 7 | return Lesson.findAll(options); 8 | } 9 | 10 | getLessonById(id) { 11 | return Lesson.findByPk(id); 12 | } 13 | 14 | getLessonByCourse(id) { 15 | return Lesson.findAll({ where: { courseId: id } }); 16 | } 17 | 18 | createLesson(props: any) { 19 | return Lesson.create(props); 20 | } 21 | 22 | updateLesson(id: Number, props: any) { 23 | return Lesson.update(props, { where: { id: id.toString() } }); 24 | } 25 | 26 | deleteLesson(id: Number) { 27 | return Lesson.destroy({ where: { id: id.toString() } }); 28 | } 29 | } 30 | 31 | export default new LessonRepo(); 32 | -------------------------------------------------------------------------------- /src/handlers/errorHandler.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction } from 'express'; 2 | import * as winston from 'winston'; 3 | 4 | const file = new winston.transports.File({ 5 | filename: '../logs/error.log', 6 | level: 'error', 7 | handleExceptions: true, 8 | }); 9 | 10 | export function unCoughtErrorHandler( 11 | err: any, 12 | req: Request, 13 | res: Response, 14 | next: NextFunction, 15 | ) { 16 | winston.error(JSON.stringify(err)); 17 | res.end({ error: err }); 18 | } 19 | 20 | export function apiErrorHandler( 21 | err: any, 22 | req: Request, 23 | res: Response, 24 | message: string, 25 | ) { 26 | const error: object = { Message: message, Request: req, Stack: err }; 27 | winston.error(JSON.stringify(error)); 28 | res.json({ Message: message }); 29 | } 30 | -------------------------------------------------------------------------------- /src/db/db.ts: -------------------------------------------------------------------------------- 1 | import { Sequelize, Options } from 'sequelize'; 2 | const dbUrl: string = process.env.DB_URL || ''; 3 | const nodeEnv: string = process.env.NODE_ENV || ''; 4 | 5 | if (!dbUrl) { 6 | console.log('Please create .env file, refer .env.sample'); 7 | process.exit(0); 8 | } 9 | 10 | let optionsObj: object = { benchmark: true, logging: console.log }; 11 | 12 | if (nodeEnv && nodeEnv === 'production') { 13 | optionsObj = { logging: false }; 14 | } 15 | const options: Options = optionsObj; 16 | 17 | export const sequelize: Sequelize = new Sequelize(dbUrl, options); 18 | 19 | sequelize 20 | .authenticate() 21 | .then(() => { 22 | console.log('Connection has been established successfully..'); 23 | }) 24 | .catch(err => { 25 | console.error('Unable to connect to the database:', err); 26 | }); 27 | -------------------------------------------------------------------------------- /src/middlewares/rateLimit.ts: -------------------------------------------------------------------------------- 1 | import * as RateLimit from 'express-rate-limit'; 2 | 3 | const env = process.env.NODE_ENV || 'dev'; 4 | const rateLimitRequest = Number(process.env.RATE_LIMIT_TIME) || 15; 5 | const rateLimitTime = Number(process.env.RATE_LIMIT_REQUEST) || 100; 6 | 7 | export default () => { 8 | if (env === 'production') { 9 | return new RateLimit({ 10 | windowMs: rateLimitTime * 60 * 1000, // 15 minutes 11 | max: rateLimitRequest, // limit each IP to 30 requests per windowMs 12 | delayMs: 0, 13 | handler: 'Rate limt exceeded, please try again later some time.', 14 | }); 15 | } 16 | return new RateLimit({ 17 | windowMs: 5 * 60 * 1000, // 5 minutes 18 | max: 3000, // limit each IP to 3000 requests per windowMs 19 | delayMs: 0, 20 | handler: 'Rate limt exceeded, please try again later some time.', 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /src/models/Lesson.ts: -------------------------------------------------------------------------------- 1 | import { sequelize } from './../db/db'; 2 | import { Model, DataTypes } from 'sequelize'; 3 | 4 | export class Lesson extends Model { 5 | public id!: number; 6 | public url!: string; 7 | public title!: string; 8 | public description!: string; 9 | public thumbnailUrl!: string; 10 | public duration!: string; 11 | public seqNo!: number; 12 | public courseId!: number; 13 | } 14 | 15 | Lesson.init( 16 | { 17 | id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, 18 | url: { type: DataTypes.STRING }, 19 | description: { type: DataTypes.TEXT }, 20 | thumbnailUrl: { type: DataTypes.STRING }, 21 | title: { type: DataTypes.STRING }, 22 | duration: { type: DataTypes.STRING }, 23 | seqNo: { type: DataTypes.INTEGER }, 24 | courseId: { type: DataTypes.INTEGER }, 25 | }, 26 | { 27 | sequelize, 28 | tableName: 'Lessons', 29 | }, 30 | ); 31 | -------------------------------------------------------------------------------- /src/controllers/CoursesCtrl.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction } from 'express'; 2 | import CourseRepo from './../repositories/CoursesRepo'; 3 | import { apiErrorHandler } from './../handlers/errorHandler'; 4 | 5 | export default class CoursesCtrl { 6 | constructor() { } 7 | 8 | async getAllCourses(req: Request, res: Response, next: NextFunction) { 9 | try { 10 | const courseList = await CourseRepo.getAllCourses({ order: ['seqNo'] }); 11 | res.json(courseList); 12 | } catch (error) { 13 | apiErrorHandler(error, req, res, 'Fetch All Courses failed.'); 14 | } 15 | } 16 | 17 | async getCourseDetails(req: Request, res: Response, next: NextFunction) { 18 | try { 19 | const courseDetails = await CourseRepo.getById(req.params.id); 20 | if (courseDetails) { 21 | return res.json(courseDetails); 22 | } else { 23 | res.status(404).send(`Lesson ${req.params.id} not found.`); 24 | } 25 | } catch (error) { 26 | apiErrorHandler(error, req, res, `Course ${req.params.id} is failed.`); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/validators/lessonValidator.ts: -------------------------------------------------------------------------------- 1 | import * as Joi from 'joi'; 2 | import { Request, Response, NextFunction } from 'express'; 3 | 4 | interface LessonRequest extends Request { 5 | value?: { body?: string }; 6 | } 7 | export class LessonValidator { 8 | constructor() { } 9 | 10 | validateBody(schema) { 11 | return async (req: LessonRequest, res: Response, next: NextFunction) => { 12 | try { 13 | const val = await schema.validateAsync(req.body); 14 | req.value = req.value ?? {}; 15 | req.value.body = req.value.body ?? val; 16 | next(); 17 | } catch (error) { 18 | res.status(400).json(error); 19 | } 20 | }; 21 | } 22 | } 23 | 24 | export const lessonSchema = Joi.object().keys({ 25 | courseId: Joi.number().integer().required(), 26 | url: Joi.string().trim().uri().required(), 27 | description: Joi.string().trim(), 28 | thumbnailUrl: Joi.string().uri(), 29 | title: Joi.string().trim().required(), 30 | duration: Joi.string(), 31 | seqNo: Joi.number(), 32 | createdAt: Joi.date(), 33 | updatedAt: Joi.date() 34 | }); 35 | -------------------------------------------------------------------------------- /src/routes/LessonRoutes.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import LessonsCtrl from '../controllers/LessonsCtrl'; 3 | import { LessonValidator, lessonSchema } from '../validators/lessonValidator'; 4 | 5 | class LessonRoutes { 6 | router = Router(); 7 | lessonsCtrl = new LessonsCtrl(); 8 | lessonValidator = new LessonValidator(); 9 | 10 | constructor() { 11 | this.intializeRoutes(); 12 | } 13 | 14 | intializeRoutes() { 15 | 16 | this.router.route('/').get(this.lessonsCtrl.getAllLessons); 17 | this.router.route('/course/:id') 18 | .get(this.lessonsCtrl.getLessonByCourse); 19 | this.router.route('/:id').get(this.lessonsCtrl.getLessonById); 20 | this.router.route('/') 21 | .post( 22 | this.lessonValidator.validateBody(lessonSchema), 23 | this.lessonsCtrl.createLesson 24 | ); 25 | this.router.route('/:id') 26 | .put( 27 | this.lessonValidator.validateBody(lessonSchema), 28 | this.lessonsCtrl.updateLesson 29 | ); 30 | this.router.route('/:id').delete(this.lessonsCtrl.deleteLesson); 31 | } 32 | } 33 | 34 | export default new LessonRoutes().router; 35 | -------------------------------------------------------------------------------- /src/models/Course.ts: -------------------------------------------------------------------------------- 1 | import { Model, DataTypes } from 'sequelize'; 2 | import { sequelize } from './../db/db'; 3 | import { Lesson } from './Lesson'; 4 | 5 | export class Course extends Model { 6 | public id!: number; 7 | public description!: string; 8 | public url!: string; 9 | public longDescription!: string; 10 | public iconUrl!: string; 11 | public tags!: string; 12 | public channelTitle!: string; 13 | public channelUrl!: string; 14 | public channelId!: string; 15 | public seqNo!: number; 16 | } 17 | 18 | Course.init( 19 | { 20 | id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, 21 | description: { type: DataTypes.STRING }, 22 | url: { type: DataTypes.STRING }, 23 | longDescription: { type: DataTypes.TEXT }, 24 | iconUrl: { type: DataTypes.STRING }, 25 | tags: { type: DataTypes.STRING }, 26 | channelTitle: { type: DataTypes.STRING }, 27 | channelUrl: { type: DataTypes.STRING }, 28 | channelId: { type: DataTypes.STRING }, 29 | seqNo: { type: DataTypes.INTEGER }, 30 | }, 31 | { 32 | sequelize, 33 | tableName: 'Courses', 34 | }, 35 | ); 36 | 37 | Course.hasMany(Lesson, { foreignKey: 'courseId', as: 'lessons' }); 38 | Lesson.belongsTo(Course, { foreignKey: 'courseId', as: 'course' }); 39 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "class-name": true, 4 | "comment-format": [true, "check-space"], 5 | "indent": [true, "spaces"], 6 | "one-line": [true, "check-open-brace", "check-whitespace"], 7 | "no-var-keyword": true, 8 | "quotemark": [true, "single", "avoid-escape"], 9 | "semicolon": [true, "always", "ignore-bound-class-methods"], 10 | "whitespace": [ 11 | true, 12 | "check-branch", 13 | "check-decl", 14 | "check-operator", 15 | "check-module", 16 | "check-separator", 17 | "check-type" 18 | ], 19 | "typedef-whitespace": [ 20 | true, 21 | { 22 | "call-signature": "nospace", 23 | "index-signature": "nospace", 24 | "parameter": "nospace", 25 | "property-declaration": "nospace", 26 | "variable-declaration": "nospace" 27 | }, 28 | { 29 | "call-signature": "onespace", 30 | "index-signature": "onespace", 31 | "parameter": "onespace", 32 | "property-declaration": "onespace", 33 | "variable-declaration": "onespace" 34 | } 35 | ], 36 | "no-internal-module": true, 37 | "no-trailing-whitespace": true, 38 | "no-null-keyword": true, 39 | "prefer-const": true, 40 | "jsdoc-format": true 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Application, urlencoded, json } from 'express'; 2 | import * as morgan from 'morgan'; 3 | import * as fs from 'fs'; 4 | import { WriteStream } from 'fs'; 5 | import * as path from 'path'; 6 | import * as helmet from 'helmet'; 7 | import * as winston from 'winston'; 8 | 9 | import rateLimiter from './middlewares/rateLimit'; 10 | import { unCoughtErrorHandler } from './handlers/errorHandler'; 11 | import Routes from './routes'; 12 | 13 | // app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc) 14 | 15 | export default class Server { 16 | constructor(app: Application) { 17 | this.config(app); 18 | new Routes(app); 19 | } 20 | 21 | public config(app: Application): void { 22 | const accessLogStream: WriteStream = fs.createWriteStream( 23 | path.join(__dirname, './logs/access.log'), 24 | { flags: 'a' } 25 | ); 26 | app.use(morgan('combined', { stream: accessLogStream })); 27 | app.use(urlencoded({ extended: true })); 28 | app.use(json()); 29 | app.use(helmet()); 30 | app.use(rateLimiter()); // apply to all requests 31 | app.use(unCoughtErrorHandler); 32 | } 33 | } 34 | 35 | process.on('beforeExit', function (err) { 36 | winston.error(JSON.stringify(err)); 37 | console.error(err); 38 | }); 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node,visualstudiocode 3 | 4 | ### Node ### 5 | # Logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | dist 11 | .idea 12 | .DS_Store 13 | tmp 14 | perf-logs 15 | v8.log 16 | *.js 17 | *.js.map 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (http://nodejs.org/api/addons.html) 44 | build/Release 45 | 46 | # Dependency directories 47 | node_modules/ 48 | jspm_packages/ 49 | 50 | # Typescript v1 declaration files 51 | typings/ 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env 70 | 71 | 72 | # End of https://www.gitignore.io/api/node,visualstudiocode 73 | 74 | *.sql 75 | links.txt 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-typescript-rest-api", 3 | "version": "1.0.0", 4 | "description": "This is a simple REST API developed using node and express with typescript", 5 | "scripts": { 6 | "start": "npm run transpile && node server.js", 7 | "dev": "concurrently \"npm:watch\" \"npm:serve\"", 8 | "serve": "nodemon server.js", 9 | "watch": "tsc -w", 10 | "transpile": "tsc", 11 | "seed": "npm run transpile && node src/db/seed.js", 12 | "lint": "tslint -c tslint.json -p tsconfig.json" 13 | }, 14 | "engines": { 15 | "node": ">=8.0" 16 | }, 17 | "keywords": [ 18 | "Node", 19 | "Typescript", 20 | "postgresql", 21 | "javascript" 22 | ], 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/nmanikiran/rest-api-node-typescript.git" 26 | }, 27 | "homepage": "https://github.com/nmanikiran/rest-api-node-typescript#readme", 28 | "bugs": { 29 | "url": "https://github.com/nmanikiran/rest-api-node-typescript/issues" 30 | }, 31 | "author": "Mani Kiran N", 32 | "license": "MIT", 33 | "devDependencies": { 34 | "@types/dotenv": "^8.2.0", 35 | "@types/express": "^4.17.11", 36 | "@types/helmet": "4.0.0", 37 | "@types/joi": "^17.2.2", 38 | "@types/node": "^15.0.1", 39 | "@types/sequelize": "^4.28.9", 40 | "@types/winston": "^2.4.4", 41 | "concurrently": "^6.0.2", 42 | "nodemon": "^2.0.7", 43 | "tslint": "^6.1.2", 44 | "typescript": "^4.2.4" 45 | }, 46 | "dependencies": { 47 | "dotenv": "^8.2.0", 48 | "express": "^4.17.1", 49 | "express-rate-limit": "^5.2.6", 50 | "helmet": "^4.5.0", 51 | "husky": "^6.0.0", 52 | "joi": "^17.4.0", 53 | "morgan": "^1.10.0", 54 | "pg": "^8.6.0", 55 | "sequelize": "^6.6.2", 56 | "winston": "^3.3.3" 57 | }, 58 | "hooks": { 59 | "pre-commit": "npm run lint" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/controllers/LessonsCtrl.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction } from 'express'; 2 | import { apiErrorHandler } from '../handlers/errorHandler'; 3 | import LessonRepo from '../repositories/LessonsRepo'; 4 | 5 | export default class LessonsCtrl { 6 | constructor() { } 7 | 8 | async getAllLessons(req: Request, res: Response, next: NextFunction) { 9 | try { 10 | const lessons = await LessonRepo.getAllLessons({ order: ['id'] }); 11 | res.json(lessons); 12 | } catch (error) { 13 | apiErrorHandler(error, req, res, 'Fetch All Lessons failed.'); 14 | } 15 | } 16 | 17 | async getLessonByCourse(req: Request, res: Response, next: NextFunction) { 18 | try { 19 | const lesson = await LessonRepo.getLessonByCourse(req.params.id); 20 | res.json(lesson); 21 | } catch (error) { 22 | apiErrorHandler( 23 | error, 24 | req, 25 | res, 26 | `Lessons in course ${req.params.id} failed.`, 27 | ); 28 | } 29 | } 30 | 31 | async getLessonById(req: Request, res: any, next: NextFunction) { 32 | try { 33 | const result = await LessonRepo.getLessonById(req.params.id); 34 | if (result) { 35 | return res.json(result); 36 | } else { 37 | res.status(404).send(`Lesson ${req.params.id} not found.`); 38 | } 39 | } catch (error) { 40 | apiErrorHandler(error, req, res, `Lesson ${req.params.id} failed.`); 41 | } 42 | } 43 | 44 | async createLesson(req: Request, res: Response, next: NextFunction) { 45 | try { 46 | const result = await LessonRepo.createLesson(req['value']['body']); 47 | res.json(result); 48 | } catch (error) { 49 | apiErrorHandler(error, req, res, 'Creation of Lesson failed.'); 50 | } 51 | } 52 | 53 | async updateLesson(req: Request, res: Response, next: NextFunction) { 54 | const id = parseInt(req.params.id); 55 | try { 56 | const result = await LessonRepo.updateLesson(id, req['value']['body']); 57 | res.json(result); 58 | } catch (error) { 59 | apiErrorHandler( 60 | error, 61 | req, 62 | res, 63 | `updation of Lesson ${req.params.id} is failed.`, 64 | ); 65 | } 66 | } 67 | 68 | async deleteLesson(req: Request, res: Response, next: NextFunction) { 69 | const id = parseInt(req.params.id); 70 | try { 71 | const result = await LessonRepo.deleteLesson(id); 72 | res.json(result); 73 | } catch (error) { 74 | apiErrorHandler( 75 | error, 76 | req, 77 | res, 78 | `deletion of Lesson ${req.params.id} is failed.`, 79 | ); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Where to start 4 | 5 | There are many different ways to contribute to **rest-api-node-typescript**'s development, just find the one that best fits with your skills. Examples of contributions we would love to receive include: 6 | 7 | - Code patches [pull request](https://help.github.com/articles/creating-a-pull-request/) 8 | - Documentation improvements 9 | - Translations(yet to come) 10 | - Bug reports 11 | - Patch reviews 12 | - UI enhancements 13 | 14 | ## Submitting a Pull Requests 15 | 16 | I welcome and encourage all pull requests. It usually will take me within 24-48 hours to respond to any issue or request. Here are some basic rules to follow to ensure the timely addition of your request: 17 | 18 | - Match the document style as closely as possible. 19 | - Please keep PR titles easy to read and descriptive of changes, this will make them easier to merge :) 20 | - Pull requests must be made against the `development` branch for this particular repository. 21 | - Check for existing [issues](https://github.com/nmanikiran/rest-api-node-typescript/issues) first, before filing an issue. 22 | - Make sure you follow the set standard as all other projects in this repo 23 | - Have fun! 24 | 25 | When contributing to this repository, please first discuss the change you wish to make via issue or any other method with the owners of this repository before making a change. 26 | 27 | Please note we have a code of conduct, please follow it in all your interactions with the project. 28 | 29 | ## Reporting Issues 30 | 31 | Have you identified a reproducible problem in this repo? Have a feature request? We want to hear about it! Here's how you can make reporting your issue as effective as possible. 32 | 33 | ##Look For an Existing Issue## 34 | Before you create a new issue, please do a search in open issues to see if the issue or feature request has already been filed. 35 | 36 | Be sure to scan through the most popular feature requests. 37 | 38 | If you find your issue already exists, make relevant comments and add your reaction. Use a reaction in place of a "+1" comment: 39 | 40 | 👍 - upvote 41 | 42 | 👎 - downvote 43 | 44 | If you cannot find an existing issue that describes your bug or feature, create a new issue using the guidelines below. 45 | 46 | ##Writing Good Bug Reports and Feature Requests## 47 | File a single issue per problem and feature request. Do not enumerate multiple bugs or feature requests in the same issue. 48 | 49 | Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar but have different causes. 50 | 51 | The more information you can provide, the more likely someone will be successful in reproducing the issue and finding a fix. 52 | 53 | Please include the following with each issue: 54 | 55 | - OS 56 | - The version of Node.js, npm / yarn 57 | - Reproducible steps (1... 2... 3...) that cause the issue 58 | - What you expected to see, versus what you actually saw 59 | - Images, animations, or a link to a video showing the issue occurring 60 | - A code snippet that demonstrates the issue or a link to a code repository the developers can easily pull down to recreate the issue locally 61 | - **Note**: Because the developers need to copy and paste the code snippet, including a code snippet as a media file (i.e. .gif) is not sufficient. 62 | - Errors from the Dev Tools Console (open from the menu: Help > Toggle Developer Tools) 63 | 64 | ##Thank You!## 65 | Your contributions to open source, large or small, make great projects like this possible. Thank you for taking the time to contribute. 66 | -------------------------------------------------------------------------------- /postman_collection/rest-api-node-typescript.postman_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "eadd1430-984a-4165-8a82-9e3f7ae84dc3", 4 | "name": "rest-api-node-typescript", 5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 6 | }, 7 | "item": [ 8 | { 9 | "name": "Get all Courses", 10 | "request": { 11 | "method": "GET", 12 | "header": [], 13 | "url": { 14 | "raw": "http://localhost:3000/api/courses/", 15 | "protocol": "http", 16 | "host": [ 17 | "localhost" 18 | ], 19 | "port": "3000", 20 | "path": [ 21 | "api", 22 | "courses", 23 | "" 24 | ] 25 | } 26 | }, 27 | "response": [] 28 | }, 29 | { 30 | "name": "Get Course details from course id including Lessons", 31 | "request": { 32 | "method": "GET", 33 | "header": [], 34 | "url": { 35 | "raw": "http://localhost:3000/api/courses/1", 36 | "protocol": "http", 37 | "host": [ 38 | "localhost" 39 | ], 40 | "port": "3000", 41 | "path": [ 42 | "api", 43 | "courses", 44 | "1" 45 | ] 46 | } 47 | }, 48 | "response": [] 49 | }, 50 | { 51 | "name": "Get All Lessons", 52 | "request": { 53 | "method": "GET", 54 | "header": [], 55 | "url": { 56 | "raw": "http://localhost:3000/api/lessons", 57 | "protocol": "http", 58 | "host": [ 59 | "localhost" 60 | ], 61 | "port": "3000", 62 | "path": [ 63 | "api", 64 | "lessons" 65 | ] 66 | } 67 | }, 68 | "response": [] 69 | }, 70 | { 71 | "name": "Get All Lessons from course id", 72 | "request": { 73 | "method": "GET", 74 | "header": [], 75 | "url": { 76 | "raw": "http://localhost:3000/api/lessons/course/1", 77 | "protocol": "http", 78 | "host": [ 79 | "localhost" 80 | ], 81 | "port": "3000", 82 | "path": [ 83 | "api", 84 | "lessons", 85 | "course", 86 | "1" 87 | ] 88 | } 89 | }, 90 | "response": [] 91 | }, 92 | { 93 | "name": "Get Lesson details from lesson id", 94 | "request": { 95 | "method": "GET", 96 | "header": [], 97 | "url": { 98 | "raw": "http://localhost:3000/api/lessons/1", 99 | "protocol": "http", 100 | "host": [ 101 | "localhost" 102 | ], 103 | "port": "3000", 104 | "path": [ 105 | "api", 106 | "lessons", 107 | "1" 108 | ] 109 | } 110 | }, 111 | "response": [] 112 | }, 113 | { 114 | "name": "Create Lesson", 115 | "request": { 116 | "method": "POST", 117 | "header": [ 118 | { 119 | "key": "Content-Type", 120 | "name": "Content-Type", 121 | "value": "application/json", 122 | "type": "text" 123 | } 124 | ], 125 | "body": { 126 | "mode": "raw", 127 | "raw": "{\n \"url\": \"https://www.youtube.com\",\n \"description\": \"This is description\",\n \"title\": \"Lesson Title\",\n \"duration\": \"00:00:56\",\n \"seqNo\": 20,\n \"courseId\": 1\n}", 128 | "options": { 129 | "raw": { 130 | "language": "json" 131 | } 132 | } 133 | }, 134 | "url": { 135 | "raw": "http://localhost:3000/api/lessons", 136 | "protocol": "http", 137 | "host": [ 138 | "localhost" 139 | ], 140 | "port": "3000", 141 | "path": [ 142 | "api", 143 | "lessons" 144 | ] 145 | } 146 | }, 147 | "response": [] 148 | }, 149 | { 150 | "name": "Delete Lesson by id", 151 | "request": { 152 | "method": "DELETE", 153 | "header": [], 154 | "url": { 155 | "raw": "http://localhost:3000/api/lessons/7", 156 | "protocol": "http", 157 | "host": [ 158 | "localhost" 159 | ], 160 | "port": "3000", 161 | "path": [ 162 | "api", 163 | "lessons", 164 | "7" 165 | ] 166 | } 167 | }, 168 | "response": [] 169 | }, 170 | { 171 | "name": "Update Lesson by id", 172 | "request": { 173 | "method": "PUT", 174 | "header": [ 175 | { 176 | "key": "Content-Type", 177 | "name": "Content-Type", 178 | "value": "application/json", 179 | "type": "text" 180 | } 181 | ], 182 | "body": { 183 | "mode": "raw", 184 | "raw": "{\n \"url\": \"https://www.youtube.com/watch?v=1JFeWDZ-2D8\",\n \"description\": \"Updated description\",\n \"thumbnailUrl\": \"https://i.ytimg.com/vi/1JFeWDZ-2D8/default.jpg\",\n \"title\": \"Day 5: Heading Tags (30 Days to Learn HTML & CSS)\",\n \"duration\": \"00:03:42\",\n \"seqNo\": 6,\n \"courseId\": 1\n}", 185 | "options": { 186 | "raw": { 187 | "language": "json" 188 | } 189 | } 190 | }, 191 | "url": { 192 | "raw": "http://localhost:3000/api/lessons/6", 193 | "protocol": "http", 194 | "host": [ 195 | "localhost" 196 | ], 197 | "port": "3000", 198 | "path": [ 199 | "api", 200 | "lessons", 201 | "6" 202 | ] 203 | } 204 | }, 205 | "response": [] 206 | } 207 | ], 208 | "protocolProfileBehavior": {} 209 | } -------------------------------------------------------------------------------- /Readme.MD: -------------------------------------------------------------------------------- 1 | # REST API with Node using Typescript 2 | 3 | This is a simple REST API developed using node and express with typescript 4 | 5 | ![alt text](https://image.ibb.co/nAd9OF/logos.png "Node Typescript") 6 | 7 | ## ❤️ Found this project useful? 8 | 9 | If you found this project useful, then please consider giving it a ⭐️ on Github and sharing it with your friends via social media. 10 | 11 | ## Requirements 12 | 13 | [Node.js](https://nodejs.org/en/), [postgresql](https://www.postgresql.org/download/) 14 | 15 | ### Getting Started 16 | 17 | ### Setup DB 18 | 19 | 1. You need to install PostgreSQL 20 | 21 | - For Windows 22 | - Install PostgreSQL and set following environment variable 23 | `C:\Program Files\PostgreSQL\10\bin`, 24 | `C:\Program Files\PostgreSQL\10\lib` 25 | - For Ubuntu 26 | 27 | - Installation 28 | `sudo apt update` 29 | `sudo apt-get install postgresql postgresql-contrib` 30 | 31 | - Manage `PostgreSQL` service 32 | `sudo systemctl {status | start | restart | stop} postgresql` 33 | 34 | 2. rename `.env-sample` to `.env` in the file the DB connection string need to be updated according to your `credentials`. 35 | ex : `postgres://:@localhost:5432/` 36 | 37 | 3. you can find the DB and other details under `src/db` 38 | create a database with the name `node-typescript-rest-api` and then run/ import the `.sql` files (extract the sql files from sql.zip). 39 | Or you can run `npm run seed`. 40 | 41 | 4. install `pm2` globally with `npm install -g pm2` 42 | 43 | ### Run the app locally 44 | 45 | - git clone https://github.com/nmanikiran/rest-api-node-typescript.git 46 | 47 | - `npm install` 48 | - `npm start` - This will start the application and run on port 3000 49 | - `npm run dev` - This will start the application in development mode 50 | - `npm run watch & pm2 start ecosystem.config.js` to start the application with cluster for scalability 51 | 52 | you can change port in `.env` file check `.env-sample` 53 | 54 | ## Folder Structure 55 | 56 | ``` 57 | src 58 | └───index.ts # Application entry point 59 | └───routes # Application routes / endpoints 60 | └───controllers # Express route controllers for all the endpoints of the app 61 | └───repositories # All the database interaction logic is here 62 | └───db # DB related files like connection / seed data 63 | └───handlers # Common logic 64 | └───logs # application logs 65 | └───middlewares # express middlewares 66 | └───models # DB Models (Postgress) 67 | └───validators # API Request object validations 68 | 69 | ``` 70 | 71 | ## Features 72 | 73 | - CRUD operations for Courses 74 | - CRUD operations for Lessons 75 | - REST API Request object validations - Basic 76 | - Error Logs 77 | - Setup docs 78 | - Seeder for DB 79 | 80 | ## Planned 81 | 82 | - \[ ] JWT login 83 | - \[ ] Unit Testing 84 | - \[x] Postman collections 85 | - \[ ] Improve request Object Validations 86 | - \[ ] Improve Error Messages for request failures 87 | - \[x] Project / DB Setup in Ubuntu - Docs 88 | - \[ ] Security 89 | - \[ ] Hosting 90 | 91 | ## REST Services 92 | 93 | The application exposes a few REST endpoints 94 | 95 | `HTTP` `GET` /api/lessons 96 | 97 | `HTTP` `GET` /api/lessons/:id 98 | 99 | `HTTP` `GET` /api/courses 100 | 101 | You can use the following code snippet to call the secured endpoint: 102 | 103 | ```js 104 | fetch("http://localhost:3000/api/courses", { 105 | method: "GET", 106 | headers: { 107 | "Content-Type": "application/json", 108 | }, 109 | }) 110 | .then((response) => { 111 | if (response.status === 200) { 112 | response.json().then((j) => console.log(j)); 113 | } else { 114 | console.log("ERROR", response.status); 115 | } 116 | }) 117 | .catch((error) => console.log(error)); 118 | ``` 119 | 120 | ## Created & Maintained By 121 | 122 | 123 | 124 | 131 | 137 | 138 |
Mani Kiran
Mani Kiran N

125 | 💻 126 | 📖 127 | 🤔 128 | 👀 129 | 🚧 130 |
Tushar Gupta
Tushar Gupta

132 | 💻 133 | 📖 134 | 💬 135 | 🚧 136 |
139 | 140 | Feel free to reach out to me through @nmanikiran if you have any questions or feedback! 141 | 142 | ## Recommended / Preferred 143 | 144 | [VSCode](https://code.visualstudio.com/download) 145 | 146 | ## Thanks & Credits to 147 | 148 | - Envato Tuts+ [30 Days to Learn HTML & CSS (Full Course)](https://www.youtube.com/playlist?list=PLgGbWId6zgaWZkPFI4Sc9QXDmmOWa1v5F) 149 | - Wes Bos [JavaScript30](https://www.youtube.com/playlist?list=PLu8EoSxDXHP6CGK4YVJhL_VWetA865GOH) 150 | - CodeWorkr [REST API with Node (Express & MongoDB)](https://www.youtube.com/playlist?list=PLSpJkDDmpFZ5rZ5-Aur9WRNsBDSUS-0B9) 151 | - Tyler McGinnis [Advanced JavaScript](https://www.youtube.com/playlist?list=PLqrUy7kON1meuCvGp2D6yTglZhPTT_s_f) 152 | -------------------------------------------------------------------------------- /src/db/courses.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "30 Days to Learn HTML & CSS (Full Course)", 4 | "url": "https://www.youtube.com/playlist?list=PLgGbWId6zgaWZkPFI4Sc9QXDmmOWa1v5F", 5 | "longDescription": "Even if your goal is not to become a web designer, learning HTML and CSS can be an amazing tool to have in your skill-set – both in the workplace, and at home. If this has been on your to-do list for some time, why don’t you take thirty days and join me? Give me around ten minutes every day, and I’ll teach you the essentials of HTML and CSS.For more Web Design courses, see: https://webdesign.tutsplus.com/courses/", 6 | "iconUrl": "https://i.ytimg.com/vi/yTHTo28hwTQ/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDRRxEIZSv7coxKikXYwTz4bapQFQ", 7 | "seqNo": 0, 8 | "tags": "BEGINNER", 9 | "channelTitle": "Envato Tuts+", 10 | "channelUrl": "https://www.youtube.com/user/TutsPremium", 11 | "channelId": "UC8lxnUR_CzruT2KA6cb7p0Q", 12 | "lessons": [ 13 | { 14 | "seqNo": 1, 15 | "title": "Course Introduction (30 Days to Learn HTML and CSS)", 16 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/yTHTo28hwTQ\/default.jpg", 17 | "description": "This is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_yTHTo28hwTQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_yTHTo28hwTQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_yTHTo28hwTQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEven if your goal is not to become a web designer, learning HTML and CSS can be an amazing tool to have in your skill-set -- both in the workplace, and at home. If this has been on your to-do list for some time, why don't you take thirty days and join me? Give me around ten minutes every day, and I'll teach you the essentials of HTML and CSS.\n\nAnd don't worry... we start at the beginning!\n\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_yTHTo28hwTQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_yTHTo28hwTQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 18 | "url": "https://www.youtube.com/watch?v=yTHTo28hwTQ", 19 | "duration": "00:00:56" 20 | }, 21 | { 22 | "seqNo": 2, 23 | "title": "Day 1: Your First Webpage (30 Days to Learn HTML & CSS)", 24 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/bfqBUDk99Tc\/default.jpg", 25 | "description": "In this lesson, you'll learn how to make a working web page that displays the words, \"Hello world.\"\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_bfqBUDk99Tc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_bfqBUDk99Tc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_bfqBUDk99Tc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_bfqBUDk99Tc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_bfqBUDk99Tc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 26 | "url": "https://www.youtube.com/watch?v=bfqBUDk99Tc", 27 | "duration": "00:09:51" 28 | }, 29 | { 30 | "seqNo": 3, 31 | "title": "Day 2: Finding a Proper Code Editor (30 Days to Learn HTML & CSS)", 32 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/-8IoQTg5Ybs\/default.jpg", 33 | "description": "Before we continue on with formatting our text, I don't want you to be using NotePad or Text Edit. Instead, we should be using a code editor that was specifically created for the purposes of writing code.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_-8IoQTg5Ybs&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_-8IoQTg5Ybs&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_-8IoQTg5Ybs&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_-8IoQTg5Ybs&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_-8IoQTg5Ybs&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 34 | "url": "https://www.youtube.com/watch?v=-8IoQTg5Ybs", 35 | "duration": "00:07:16" 36 | }, 37 | { 38 | "seqNo": 4, 39 | "title": "Day 3: Lists (30 Days to Learn HTML & CSS)", 40 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/KHT6scxGm38\/default.jpg", 41 | "description": "Welcome to Day 3. Today we're going to cover how to create a list of items using HTML.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_KHT6scxGm38&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_KHT6scxGm38&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_KHT6scxGm38&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_KHT6scxGm38&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_KHT6scxGm38&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 42 | "url": "https://www.youtube.com/watch?v=KHT6scxGm38", 43 | "duration": "00:12:37" 44 | }, 45 | { 46 | "seqNo": 5, 47 | "title": "Day 4: Parent-Child Relationships (30 Days to Learn HTML & CSS)", 48 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/Pf8xmAZYZC4\/default.jpg", 49 | "description": "While we touched on parent-child relationships in the previous episode, we need to focus on it a little more specifically today.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_Pf8xmAZYZC4&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_Pf8xmAZYZC4&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_Pf8xmAZYZC4&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_Pf8xmAZYZC4&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_Pf8xmAZYZC4&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 50 | "url": "https://www.youtube.com/watch?v=Pf8xmAZYZC4", 51 | "duration": "00:05:19" 52 | }, 53 | { 54 | "seqNo": 6, 55 | "title": "Day 5: Heading Tags (30 Days to Learn HTML & CSS)", 56 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/1JFeWDZ-2D8\/default.jpg", 57 | "description": "Up until now, we've only briefly touched on the idea of headings. Let's dig a bit deeper and learn about all of the headings that are available to us.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_1JFeWDZ-2D8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_1JFeWDZ-2D8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nutm_campaign=yt_tutsplus_1JFeWDZ-2D8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_1JFeWDZ-2D8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_1JFeWDZ-2D8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_1JFeWDZ-2D8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 58 | "url": "https://www.youtube.com/watch?v=1JFeWDZ-2D8", 59 | "duration": "00:03:42" 60 | }, 61 | { 62 | "seqNo": 7, 63 | "title": "Day 6: Blockquotes (30 Days to Learn HTML & CSS)", 64 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/P7KU6mqdmJ0\/default.jpg", 65 | "description": "Sometimes we need to quote somebody, and we can do that within HTML by using what's known as the blockquote element.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_P7KU6mqdmJ0&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_P7KU6mqdmJ0&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_P7KU6mqdmJ0&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_P7KU6mqdmJ0&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_P7KU6mqdmJ0&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 66 | "url": "https://www.youtube.com/watch?v=P7KU6mqdmJ0", 67 | "duration": "00:02:36" 68 | }, 69 | { 70 | "seqNo": 8, 71 | "title": "Day 7: Anchors (30 Days to Learn HTML & CSS)", 72 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/xIFZdFeGgoE\/default.jpg", 73 | "description": "Today we're going to learn about anchor tags. They allow us to connect one page to another.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_xIFZdFeGgoE&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_xIFZdFeGgoE&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_xIFZdFeGgoE&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_xIFZdFeGgoE&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_xIFZdFeGgoE&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 74 | "url": "https://www.youtube.com/watch?v=xIFZdFeGgoE", 75 | "duration": "00:08:59" 76 | }, 77 | { 78 | "seqNo": 9, 79 | "title": "Day 8: Your First Stylesheet (30 Days to Learn HTML & CSS)", 80 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/o1Vqr1MdRmg\/default.jpg", 81 | "description": "In the previous episode we noted how, by default, the browser will make anchor tags blue if you've never visited the link before. In this lesson, we'll learn how to customize this by using an attribute called 'style'. Then, we'll explore how to achieve the same thing by using a CSS stylesheet.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_o1Vqr1MdRmg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_o1Vqr1MdRmg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_o1Vqr1MdRmg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_o1Vqr1MdRmg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_o1Vqr1MdRmg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 82 | "url": "https://www.youtube.com/watch?v=o1Vqr1MdRmg", 83 | "duration": "00:09:47" 84 | }, 85 | { 86 | "seqNo": 10, 87 | "title": "Day 9: Clean Project Structures (30 Days to Learn HTML & CSS)", 88 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/g7js1fW4AZw\/default.jpg", 89 | "description": "It's considered a best practice to always divide your images, CSS files and JavaScript files into their own folders. In this lesson you'll learn about making sure all of your HTML & CSS projects are well organized and clean.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_g7js1fW4AZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_g7js1fW4AZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_g7js1fW4AZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_g7js1fW4AZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_g7js1fW4AZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 90 | "url": "https://www.youtube.com/watch?v=g7js1fW4AZw", 91 | "duration": "00:01:59" 92 | }, 93 | { 94 | "seqNo": 11, 95 | "title": "Day 10: Images (30 Days to Learn HTML & CSS)", 96 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/xLDZvePzgK8\/default.jpg", 97 | "description": "We want to be able to display an image on our HTML page. In this lesson, we'll learn the various ways to achieve this.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_xLDZvePzgK8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_xLDZvePzgK8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_xLDZvePzgK8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_xLDZvePzgK8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_xLDZvePzgK8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 98 | "url": "https://www.youtube.com/watch?v=xLDZvePzgK8", 99 | "duration": "00:04:34" 100 | }, 101 | { 102 | "seqNo": 12, 103 | "title": "Day 11: The Necessity of Divs (30 Days to Learn HTML & CSS)", 104 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/28z80vRCHYo\/default.jpg", 105 | "description": "Divs are a way to position your content, and allow you to style a variety of elements at once. You'll use them often as you code in HTML and CSS.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_28z80vRCHYo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_28z80vRCHYo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_28z80vRCHYo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_28z80vRCHYo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_28z80vRCHYo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 106 | "url": "https://www.youtube.com/watch?v=28z80vRCHYo", 107 | "duration": "00:07:12" 108 | }, 109 | { 110 | "seqNo": 13, 111 | "title": "Day 12: IDs and Classes (30 Days to Learn HTML & CSS)", 112 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/4A2NP5TdDBg\/default.jpg", 113 | "description": "In today's lesson, we're going to be taking a look at IDs and classes. We can use these to assign labels to specific elements so that we can then target them within our stylesheets.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_4A2NP5TdDBg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_4A2NP5TdDBg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_4A2NP5TdDBg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_4A2NP5TdDBg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_4A2NP5TdDBg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 114 | "url": "https://www.youtube.com/watch?v=4A2NP5TdDBg", 115 | "duration": "00:08:30" 116 | }, 117 | { 118 | "seqNo": 14, 119 | "title": "Day 13: An Assignment (30 Days to Learn HTML & CSS)", 120 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/bEuTfgwb6lU\/default.jpg", 121 | "description": "For today, you're not going to be learning from me specifically -- you're going to put some of what you've learned to the test in your first assignment!\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_bEuTfgwb6lU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_bEuTfgwb6lU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_bEuTfgwb6lU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_bEuTfgwb6lU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_bEuTfgwb6lU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 122 | "url": "https://www.youtube.com/watch?v=bEuTfgwb6lU", 123 | "duration": "00:01:32" 124 | }, 125 | { 126 | "seqNo": 15, 127 | "title": "Day 14: Assignment Solutions (30 Days to Learn HTML & CSS)", 128 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/yb_xJJXUvyg\/default.jpg", 129 | "description": "Welcome back. Today we're going to work through the solutions to the assignment set yesterday.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_yb_xJJXUvyg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_yb_xJJXUvyg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_yb_xJJXUvyg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_yb_xJJXUvyg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_yb_xJJXUvyg&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 130 | "url": "https://www.youtube.com/watch?v=yb_xJJXUvyg", 131 | "duration": "00:08:37" 132 | }, 133 | { 134 | "seqNo": 16, 135 | "title": "Day 15: Floats, and a Simple Layout (30 Days to Learn HTML & CSS)", 136 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/4qEh8bwDW0I\/default.jpg", 137 | "description": "Today I'm going to teach you about CSS floats. We can use floats to create the effect of columns.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_4qEh8bwDW0I&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_4qEh8bwDW0I&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_4qEh8bwDW0I&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_4qEh8bwDW0I&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_4qEh8bwDW0I&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 138 | "url": "https://www.youtube.com/watch?v=4qEh8bwDW0I", 139 | "duration": "00:13:57" 140 | }, 141 | { 142 | "seqNo": 17, 143 | "title": "Day 16: Navigation and Lists (30 Days to Learn HTML & CSS)", 144 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/f62FD8t4aPU\/default.jpg", 145 | "description": "Today we're going to be focusing on navigation. How would you create a navigation list for your website? This is something that every web site has in common, so it's really important you learn how to do this.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_f62FD8t4aPU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_f62FD8t4aPU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_f62FD8t4aPU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_f62FD8t4aPU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_f62FD8t4aPU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 146 | "url": "https://www.youtube.com/watch?v=f62FD8t4aPU", 147 | "duration": "00:06:16" 148 | }, 149 | { 150 | "seqNo": 18, 151 | "title": "Day 17: Introduction to Forms (30 Days to Learn HTML & CSS)", 152 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/4DS4z20ZGyI\/default.jpg", 153 | "description": "\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_4DS4z20ZGyI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nToday we're going to focus on forms. Contact forms, registration forms... what are the necessary HTML elements we should use to display form fields?\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_4DS4z20ZGyI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_4DS4z20ZGyI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_4DS4z20ZGyI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_4DS4z20ZGyI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 154 | "url": "https://www.youtube.com/watch?v=4DS4z20ZGyI", 155 | "duration": "00:15:47" 156 | }, 157 | { 158 | "seqNo": 19, 159 | "title": "Day 18: Image Replacement (30 Days to Learn HTML & CSS)", 160 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/jnG3mtEhpRQ\/default.jpg", 161 | "description": "Often you don't want to use text for your logo. Even though it makes sense to add the name of your business within an H1 tag, you might prefer to add an image in place of your logo. How would you do that?\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_jnG3mtEhpRQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_jnG3mtEhpRQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_jnG3mtEhpRQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_jnG3mtEhpRQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_jnG3mtEhpRQ&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 162 | "url": "https://www.youtube.com/watch?v=jnG3mtEhpRQ", 163 | "duration": "00:06:31" 164 | }, 165 | { 166 | "seqNo": 20, 167 | "title": "Day 19: The Basics of Typography (30 Days to Learn HTML & CSS)", 168 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/AKMgc4rzTrc\/default.jpg", 169 | "description": "Today we're going to take a look at some of the various ways we can style our text. We'll look at using fonts, color, letter spacing, and size.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_AKMgc4rzTrc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_AKMgc4rzTrc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_AKMgc4rzTrc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_AKMgc4rzTrc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_AKMgc4rzTrc&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 170 | "url": "https://www.youtube.com/watch?v=AKMgc4rzTrc", 171 | "duration": "00:10:21" 172 | }, 173 | { 174 | "seqNo": 21, 175 | "title": "Day 20: Relative and Absolute Positioning (30 Days to Learn HTML & CSS)", 176 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/6Z8I8sOinUo\/default.jpg", 177 | "description": "Today we're going to take a look at something that confuses a lot of beginning HTML and CSS designers, and it's called positioning. More specifically, the difference between what we call absolute positioning and relative positioning.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_6Z8I8sOinUo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_6Z8I8sOinUo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_6Z8I8sOinUo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_6Z8I8sOinUo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_6Z8I8sOinUo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 178 | "url": "https://www.youtube.com/watch?v=6Z8I8sOinUo", 179 | "duration": "00:07:39" 180 | }, 181 | { 182 | "seqNo": 22, 183 | "title": "Day 21: Creating a Website Fragment (30 Days to Learn HTML & CSS)", 184 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/AqAFnB-z8-Q\/default.jpg", 185 | "description": "Today we're going to take a look at fragments. This will teach you the beginning process of converting designs to HTML and CSS.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_AqAFnB-z8-Q&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_AqAFnB-z8-Q&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_AqAFnB-z8-Q&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_AqAFnB-z8-Q&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_AqAFnB-z8-Q&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 186 | "url": "https://www.youtube.com/watch?v=AqAFnB-z8-Q", 187 | "duration": "00:30:46" 188 | }, 189 | { 190 | "seqNo": 23, 191 | "title": "Day 22: The Importance of Validation (30 Days to Learn HTML & CSS)", 192 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/VIgxwR9AVrk\/default.jpg", 193 | "description": "Let's refer back to the markup we created in the previous lesson. Wouldn't it be helpful to be notified when we make errors in creating our markup?\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_VIgxwR9AVrk&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_VIgxwR9AVrk&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_VIgxwR9AVrk&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_VIgxwR9AVrk&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_VIgxwR9AVrk&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 194 | "url": "https://www.youtube.com/watch?v=VIgxwR9AVrk", 195 | "duration": "00:05:36" 196 | }, 197 | { 198 | "seqNo": 24, 199 | "title": "Day 23: Zen Coding (30 Days to Learn HTML & CSS)", 200 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/65QhaSFuxdo\/default.jpg", 201 | "description": "Zen coding is a popular way to rapidly create markup. You can grab it here.\nUpdate -- It seems that the Zen Coding installation process for Sublime Text 2 has changed a bit in recent months. Refer here for instructions: http:\/\/jdfwarrior.tumblr.com\/post\/13204904090\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_65QhaSFuxdo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_65QhaSFuxdo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_65QhaSFuxdo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_65QhaSFuxdo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_65QhaSFuxdo&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 202 | "url": "https://www.youtube.com/watch?v=65QhaSFuxdo", 203 | "duration": "00:06:33" 204 | }, 205 | { 206 | "seqNo": 25, 207 | "title": "Day 24: Resets and Normalizing (30 Days to Learn HTML & CSS)", 208 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/IgFfsZfkd24\/default.jpg", 209 | "description": "In the next two lessons, I'm going to teach you about using reset stylesheets and grids.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_IgFfsZfkd24&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_IgFfsZfkd24&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_IgFfsZfkd24&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_IgFfsZfkd24&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_IgFfsZfkd24&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 210 | "url": "https://www.youtube.com/watch?v=IgFfsZfkd24", 211 | "duration": "00:05:02" 212 | }, 213 | { 214 | "seqNo": 26, 215 | "title": "Day 25: CSS Frameworks (30 Days to Learn HTML & CSS)", 216 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/tm84gW72KFU\/default.jpg", 217 | "description": "It's fairly common for designers to use CSS frameworks. They're a collection of styles that make it easier to build our designs. One of the most popular is called the 960 Grid System, and this is the framework that we'll explore today.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_tm84gW72KFU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_tm84gW72KFU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_tm84gW72KFU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_tm84gW72KFU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_tm84gW72KFU&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 218 | "url": "https://www.youtube.com/watch?v=tm84gW72KFU", 219 | "duration": "00:17:51" 220 | }, 221 | { 222 | "seqNo": 27, 223 | "title": "Day 26: Final Project Markup (30 Days to Learn HTML & CSS)", 224 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/CilS1-ukeUA\/default.jpg", 225 | "description": "Now that you've learned the basics of HTML and CSS, it's time to start doing what you really want to be doing: building websites! We're going to get started converting a Photoshop design into a real website.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_CilS1-ukeUA&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_CilS1-ukeUA&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_CilS1-ukeUA&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_CilS1-ukeUA&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_CilS1-ukeUA&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 226 | "url": "https://www.youtube.com/watch?v=CilS1-ukeUA", 227 | "duration": "00:11:31" 228 | }, 229 | { 230 | "seqNo": 28, 231 | "title": "Day 27: Slicing a PSD (30 Days to Learn HTML & CSS)", 232 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/j4kTLpezHDI\/default.jpg", 233 | "description": "When we last left off we'd finished our markup, so let's return to Photoshop and begin slicing out any necessary assets for our design.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_j4kTLpezHDI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_j4kTLpezHDI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_j4kTLpezHDI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_j4kTLpezHDI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_j4kTLpezHDI&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 234 | "url": "https://www.youtube.com/watch?v=j4kTLpezHDI", 235 | "duration": "00:08:40" 236 | }, 237 | { 238 | "seqNo": 29, 239 | "title": "Day 28: How to Create Snippets (30 Days to Learn HTML & CSS)", 240 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/Hr9dv5FCpZw\/default.jpg", 241 | "description": "In programs like TextMate and Sublime (or whatever program you're using), they generally have some snippets built in. But often, it's best to create your own customized snippets to help you code more efficiently.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_Hr9dv5FCpZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_Hr9dv5FCpZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_Hr9dv5FCpZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_Hr9dv5FCpZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_Hr9dv5FCpZw&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 242 | "url": "https://www.youtube.com/watch?v=Hr9dv5FCpZw", 243 | "duration": "00:03:35" 244 | }, 245 | { 246 | "seqNo": 30, 247 | "title": "Day 29: The CSS for Our Website (30 Days to Learn HTML & CSS)", 248 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/zvSR_2v5xj8\/default.jpg", 249 | "description": "In this lesson we'll begin styling the markup for our website.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_zvSR_2v5xj8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_zvSR_2v5xj8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_zvSR_2v5xj8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_zvSR_2v5xj8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_zvSR_2v5xj8&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 250 | "url": "https://www.youtube.com/watch?v=zvSR_2v5xj8", 251 | "duration": "00:30:30" 252 | }, 253 | { 254 | "seqNo": 31, 255 | "title": "Day 30: Completing the Website (30 Days to Learn HTML & CSS)", 256 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/I9dNFHasF_U\/default.jpg", 257 | "description": "In the previous lesson we built the layout for our website. We need to finish up by tweaking our layout until it's complete.\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_I9dNFHasF_U&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nThis is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_I9dNFHasF_U&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/webdesign.tutsplus.com?utm_campaign=yt_tutsplus_I9dNFHasF_U&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_I9dNFHasF_U&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_I9dNFHasF_U&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 258 | "url": "https://www.youtube.com/watch?v=I9dNFHasF_U", 259 | "duration": "00:17:27" 260 | }, 261 | { 262 | "seqNo": 32, 263 | "title": "Course Exit (30 Days to Learn HTML & CSS)", 264 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/cUgpPAP0lUM\/default.jpg", 265 | "description": "This is part of the free Envato Tuts+ course 30 Days to Learn HTML & CSS: https:\/\/webdesign.tutsplus.com\/courses\/30-days-to-learn-html-css?utm_campaign=yt_tutsplus_cUgpPAP0lUM&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Browse WordPress Themes and Plugins: https:\/\/elements.envato.com\/wordpress?utm_campaign=yt_tutsplus_cUgpPAP0lUM&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nFor more great web design courses and tutorials go to: https:\/\/tutsplus.com\/?utm_campaign=yt_tutsplus_cUgpPAP0lUM&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nWe hope you've enjoyed learning HTML and CSS with the new Tuts+ Premium. If you'd like to progress to more advanced material, including CSS3, join the mailing list below. We'll let you know when more web development and design courses are available.\n\nIf you know anyone who'd like to learn HTML and CSS, we hope you'll consider sharing this course with them.\n\nHappy coding!u take thirty days and join me? Give me around ten minutes every day, and I'll teach you the essentials of HTML and CSS.\n\nAnd don't worry... we start at the beginning!\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nEnvato Tuts+\nDiscover free how-to tutorials and online courses. Design a logo, create a website, build an app, or learn a new skill: https:\/\/tutsplus.com?utm_campaign=yt_tutsplus_cUgpPAP0lUM&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\nEnvato Elements\nAll the creative assets you need under one subscription. Customize your project by adding unique photos, fonts, graphics, and themes.\n\u25ba Download Unlimited Stock Photos, Fonts & Templates with Envato Elements: https:\/\/elements.envato.com?utm_campaign=yt_tutsplus_cUgpPAP0lUM&utm_medium=referral&utm_source=youtube.com&utm_content=description\n\n\u25ba Subscribe to Envato Tuts+ on YouTube: https:\/\/www.youtube.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Twitter: https:\/\/twitter.com\/tutsplus\n\u25ba Follow Envato Tuts+ on Facebook: https:\/\/www.facebook.com\/tutsplus\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 266 | "url": "https://www.youtube.com/watch?v=cUgpPAP0lUM", 267 | "duration": "00:00:40" 268 | } 269 | ] 270 | }, 271 | { 272 | "description": "JavaScript30", 273 | "url": "https://www.youtube.com/playlist?list=PLu8EoSxDXHP6CGK4YVJhL_VWetA865GOH", 274 | "longDescription": "A 30 day Vanilla JavaScript Challenge! Grab all the videos, exercises and coded solutions over at https://JavaScript30.com", 275 | "iconUrl": "https://i.ytimg.com/vi/VuN8qwZoego/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLC3utIx9wVKvmPBcZs4O0OrIXa9zg", 276 | "seqNo": 1, 277 | "tags": "INTERMEDIATE", 278 | "channelTitle": "Wes Bos", 279 | "channelUrl": "https://www.youtube.com/user/wesbos/", 280 | "channelId": "UCoebwHSTvwalADTJhps0emA", 281 | "lessons": [ 282 | { 283 | "seqNo": 1, 284 | "title": "Make a JavaScript Drum Kit in Vanilla JS", 285 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/VuN8qwZoego\/default.jpg", 286 | "description": "Day 1 of 30. Let's make a JavaScript Drum kit and bunch along the way. Get all 30 videos and Starter files for free over at JavaScript30.com.", 287 | "url": "https://www.youtube.com/watch?v=VuN8qwZoego", 288 | "duration": "00:19:39" 289 | }, 290 | { 291 | "seqNo": 2, 292 | "title": "We build a CSS + JS Clock in Vanilla JS", 293 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/xu87YWbr4X0\/default.jpg", 294 | "description": "Grab all 30 videos and starter files for free over at https:\/\/JavaScript30.com", 295 | "url": "https://www.youtube.com/watch?v=xu87YWbr4X0", 296 | "duration": "00:10:44" 297 | }, 298 | { 299 | "seqNo": 3, 300 | "title": "Woah! CSS Variables?!", 301 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/AHLNzv13c2I\/default.jpg", 302 | "description": "Today we learn all about how to use CSS variables and update them with JavaScript. Grab all 30 videos and starter files over at https:\/\/JavaScript30.com", 303 | "url": "https://www.youtube.com/watch?v=AHLNzv13c2I", 304 | "duration": "00:13:14" 305 | }, 306 | { 307 | "seqNo": 4, 308 | "title": "JavaScript Array Cardio Practice - Day 1", 309 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/HB1ZC7czKRs\/default.jpg", 310 | "description": "Today we sweat! In order to do the rest of the JavaScript30 exercises, we need to get really good at working with Arrays in JavaScript. Grab all the exercises and code samples at https:\/\/JavaScript30.com", 311 | "url": "https://www.youtube.com/watch?v=HB1ZC7czKRs", 312 | "duration": "00:23:27" 313 | }, 314 | { 315 | "seqNo": 5, 316 | "title": "Flexbox + JavaScript Image Gallery", 317 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/9eif30i26jg\/default.jpg", 318 | "description": "Today we build a pretty nifty image gallery using Flexbox, CSS transitions and a sprinkle of JS to get things interactive. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 319 | "url": "https://www.youtube.com/watch?v=9eif30i26jg", 320 | "duration": "00:13:10" 321 | }, 322 | { 323 | "seqNo": 6, 324 | "title": "Ajax Type Ahead with fetch() ", 325 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/y4gZMJKAeWs\/default.jpg", 326 | "description": "Today we build an Ajax type ahead with vanilla JS. Grab all the videos and starter files over at https:\/\/JavaScript30.com", 327 | "url": "https://www.youtube.com/watch?v=y4gZMJKAeWs", 328 | "duration": "00:17:22" 329 | }, 330 | { 331 | "seqNo": 7, 332 | "title": ".some(), .every(), .find() and [...SPREADS] \u2014 Array Cardio Day 2", 333 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/QNmRfyNg1lw\/default.jpg", 334 | "description": "Day 2 of Array Cardio. Grab all the videos and starter files over at https:\/\/JavaScript30.com", 335 | "url": "https://www.youtube.com/watch?v=QNmRfyNg1lw", 336 | "duration": "00:07:16" 337 | }, 338 | { 339 | "seqNo": 8, 340 | "title": "Let's build something fun with HTML5 Canvas ", 341 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/8ZGAzJ0drl0\/default.jpg", 342 | "description": "Day 8 o", 343 | "url": "https://www.youtube.com/watch?v=8ZGAzJ0drl0", 344 | "duration": "00:18:02" 345 | }, 346 | { 347 | "seqNo": 9, 348 | "title": "14 Must Know Chrome Dev Tools Tricks ", 349 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/xkzDaKwinA8\/default.jpg", 350 | "description": "Hit that Subscribe button for more like this", 351 | "url": "https://www.youtube.com/watch?v=xkzDaKwinA8", 352 | "duration": "00:10:36" 353 | }, 354 | { 355 | "seqNo": 10, 356 | "title": "JS Checkbox Challenge", 357 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/RIPYsKx1iiU\/default.jpg", 358 | "description": "Today we build a Gmail style interaction for holding shift while you select checkboxes. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 359 | "url": "https://www.youtube.com/watch?v=RIPYsKx1iiU", 360 | "duration": "00:11:19" 361 | }, 362 | { 363 | "seqNo": 11, 364 | "title": "Custom HTML5 Video Player ", 365 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/yx-HYerClEA\/default.jpg", 366 | "description": "Today we build a custom HTML5 video player interface with HTML, CSS and JavaScript. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 367 | "url": "https://www.youtube.com/watch?v=yx-HYerClEA", 368 | "duration": "00:24:34" 369 | }, 370 | { 371 | "seqNo": 12, 372 | "title": "JavaScript KONAMI CODE", 373 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/_A5eVOIqGLU\/default.jpg", 374 | "description": "Today we learn about Key sequence detection with JavaScript. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 375 | "url": "https://www.youtube.com/watch?v=_A5eVOIqGLU", 376 | "duration": "00:05:09" 377 | }, 378 | { 379 | "seqNo": 13, 380 | "title": "Vanilla JavaScript Slide In on Scroll ", 381 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/uzRsENVD3W8\/default.jpg", 382 | "description": "Today we learn how to use the scroll event to detect when a nav should be fixed.", 383 | "url": "https://www.youtube.com/watch?v=uzRsENVD3W8", 384 | "duration": "00:12:58" 385 | }, 386 | { 387 | "seqNo": 14, 388 | "title": "JavaScript Fundamentals: Reference VS Cop", 389 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/YnfwDQ5XYF4\/default.jpg", 390 | "description": "Today we talk about something that isn't all that fun, but is important to know - reference vs copy. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 391 | "url": "https://www.youtube.com/watch?v=YnfwDQ5XYF4", 392 | "duration": "00:11:29" 393 | }, 394 | { 395 | "seqNo": 15, 396 | "title": "How LocalStorage and Event Delegation work", 397 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/YL1F4dCUlLc\/default.jpg", 398 | "description": "Today we learn all about Local Storage in the browser and how to use something called Event Delegation to handle events on elements created in the future. \n\nGrab all the exercises and starter files over at https:\/\/JavaScript30.com", 399 | "url": "https://www.youtube.com/watch?v=YL1F4dCUlLc", 400 | "duration": "00:30:24" 401 | }, 402 | { 403 | "seqNo": 16, 404 | "title": "CSS Text Shadow on Mouse Move Effect ", 405 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/zaz9gLI-Xac\/default.jpg", 406 | "description": "Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 407 | "url": "https://www.youtube.com/watch?v=zaz9gLI-Xac", 408 | "duration": "00:11:23" 409 | }, 410 | { 411 | "seqNo": 17, 412 | "title": "JavaScript Practice: Sorting Band Names without articles ", 413 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/PEEo-2mRQ7A\/default.jpg", 414 | "description": "Today we learn how to sort HTML elements based based on their text content. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 415 | "url": "https://www.youtube.com/watch?v=PEEo-2mRQ7A", 416 | "duration": "00:07:10" 417 | }, 418 | { 419 | "seqNo": 18, 420 | "title": "How JavaScript's Array Reduce Works ", 421 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/SadWPo2KZWg\/default.jpg", 422 | "description": "", 423 | "url": "https://www.youtube.com/watch?v=SadWPo2KZWg", 424 | "duration": "00:12:57" 425 | }, 426 | { 427 | "seqNo": 19, 428 | "title": "Unreal Webcam Fun with getUserMedia() and HTML5 Canvas ", 429 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/ElWFcBlVk-o\/default.jpg", 430 | "description": "today we use getUserMedia and Canvas to capture a video stream from a user's webcam and manipulate the pixels. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 431 | "url": "https://www.youtube.com/watch?v=ElWFcBlVk-o", 432 | "duration": "00:30:20" 433 | }, 434 | { 435 | "seqNo": 20, 436 | "title": "JavaScript Speech Recognitio", 437 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/0mJC0A72Fnw\/default.jpg", 438 | "description": "Today we learn how to use the built in Speech Recognition in the browser. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 439 | "url": "https://www.youtube.com/watch?v=0mJC0A72Fnw", 440 | "duration": "00:13:21" 441 | }, 442 | { 443 | "seqNo": 21, 444 | "title": "JavaScript Geolocation based Speedometer and Compass ", 445 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/X7Cbtra0C6I\/default.jpg", 446 | "description": "We make a really sweet compass and speedometer with just JavaScript! Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 447 | "url": "https://www.youtube.com/watch?v=X7Cbtra0C6I", 448 | "duration": "00:08:51" 449 | }, 450 | { 451 | "seqNo": 22, 452 | "title": "JavaScript Exercise: Follow Along Links ", 453 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/POP_qri7RA8\/default.jpg", 454 | "description": "Today we learn how to make those cool follow along links in JavaScript. This will set us up nicely for the Stripe follow along example we will do in a coming video. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 455 | "url": "https://www.youtube.com/watch?v=POP_qri7RA8", 456 | "duration": "00:09:25" 457 | }, 458 | { 459 | "seqNo": 23, 460 | "title": "JavaScript Text-To-Speech ", 461 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/saCpKH_xdgs\/default.jpg", 462 | "description": "We do Speech Synthesis with JavaScript in today's lesson. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 463 | "url": "https://www.youtube.com/watch?v=saCpKH_xdgs", 464 | "duration": "00:16:56" 465 | }, 466 | { 467 | "seqNo": 24, 468 | "title": "Vanilla JavaScript Sticky Nav ", 469 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/5FLOBCGH3_U\/default.jpg", 470 | "description": "Today we learn how to make a sticky nav in JavaScript! Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 471 | "url": "https://www.youtube.com/watch?v=5FLOBCGH3_U", 472 | "duration": "00:10:02" 473 | }, 474 | { 475 | "seqNo": 25, 476 | "title": "JavaScript Event Capture, Propagation and Bubbling ", 477 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/F1anRyL37lE\/default.jpg", 478 | "description": "All about those confusing event things in JavaScript. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 479 | "url": "https://www.youtube.com/watch?v=F1anRyL37lE", 480 | "duration": "00:09:10" 481 | }, 482 | { 483 | "seqNo": 26, 484 | "title": "Stripe Follow Along Dropdown Navigation ", 485 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/GvuWJSXYQDU\/default.jpg", 486 | "description": "How to re-create the amazing Stripe dropdown follow-along navigation. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 487 | "url": "https://www.youtube.com/watch?v=GvuWJSXYQDU", 488 | "duration": "00:21:12" 489 | }, 490 | { 491 | "seqNo": 27, 492 | "title": "JavaScript Interface Challenge: Click and Drag to Scroll ", 493 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/C9EWifQ5xqA\/default.jpg", 494 | "description": "Today we make a pretty neat click and drag to scroll interface where you will learn a whole lot about JavaScript events!", 495 | "url": "https://www.youtube.com/watch?v=C9EWifQ5xqA", 496 | "duration": "00:14:10" 497 | }, 498 | { 499 | "seqNo": 28, 500 | "title": "Build a Experimental Video Speed Controller UI ", 501 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/8gYN_EDMg_M\/default.jpg", 502 | "description": "Today we build an experimental video speed controller UI. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 503 | "url": "https://www.youtube.com/watch?v=8gYN_EDMg_M", 504 | "duration": "00:09:26" 505 | }, 506 | { 507 | "seqNo": 29, 508 | "title": "Vanilla JS Countdown Timer ", 509 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/LAaf7-WuJJQ\/default.jpg", 510 | "description": "We build a custom JavaScript countdown timer from scratch with Vanilla JavaScript. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 511 | "url": "https://www.youtube.com/watch?v=LAaf7-WuJJQ", 512 | "duration": "00:21:46" 513 | }, 514 | { 515 | "seqNo": 30, 516 | "title": "Make a Whack A Mole Game with Vanilla JS ", 517 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/toNFfAaWghU\/default.jpg", 518 | "description": "You did it! Today we have fun and make a whack-a-mole game. Grab all the exercises and starter files over at https:\/\/JavaScript30.com", 519 | "url": "https://www.youtube.com/watch?v=toNFfAaWghU", 520 | "duration": "00:14:35" 521 | } 522 | ] 523 | }, 524 | { 525 | "description": "REST API with Node (Express & MongoDB)", 526 | "url": "https://www.youtube.com/playlist?list=PLSpJkDDmpFZ5rZ5-Aur9WRNsBDSUS-0B9", 527 | "longDescription": "", 528 | "iconUrl": "https://i.ytimg.com/vi/1XmwszKUNR8/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDQALHVDjwC3xI5dP4Qfh4tlB6Gpg", 529 | "seqNo": 2, 530 | "tags": "INTERMEDIATE", 531 | "channelTitle": "CodeWorkr", 532 | "channelUrl": "https://www.youtube.com/channel/UCfYTu_qAO5T7a-8rC_74Ypw", 533 | "channelId": "UCfYTu_qAO5T7a-8rC_74Ypw", 534 | "lessons": [ 535 | { 536 | "seqNo": 1, 537 | "title": "Express MongoDB REST API #1 - Introduction", 538 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/1XmwszKUNR8\/default.jpg", 539 | "description": "Introductory video where I talk about what to expect in the series to come.", 540 | "url": "https://www.youtube.com/watch?v=1XmwszKUNR8", 541 | "duration": "00:07:48" 542 | }, 543 | { 544 | "seqNo": 2, 545 | "title": "Express MongoDB REST API #2 - Code Structure", 546 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/C4DjlL2hcrM\/default.jpg", 547 | "description": "First video where we actually do some work! We start of by writing the main app.js file as well as create a folder structure that we'll keep working on in the videos to come.", 548 | "url": "https://www.youtube.com/watch?v=C4DjlL2hcrM", 549 | "duration": "00:12:26" 550 | }, 551 | { 552 | "seqNo": 3, 553 | "title": "Express MongoDB REST API #3 - Routes Design", 554 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/_lfDai47SJE\/default.jpg", 555 | "description": "In this video we'll setup the code for the routes and will get started writing our first route!", 556 | "url": "https://www.youtube.com/watch?v=_lfDai47SJE", 557 | "duration": "00:11:34" 558 | }, 559 | { 560 | "seqNo": 4, 561 | "title": "Express MongoDB REST API #4 - MongoDB\/Mongoose", 562 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/L1DGbI-U_e4\/default.jpg", 563 | "description": "In this video, we'll mostly focus on interacting with our MongoDB database using Mongoose.", 564 | "url": "https://www.youtube.com/watch?v=L1DGbI-U_e4", 565 | "duration": "00:29:34" 566 | }, 567 | { 568 | "seqNo": 5, 569 | "title": "Express MongoDB REST API #5 - Async\/Await", 570 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/9tLA4r-gqds\/default.jpg", 571 | "description": "In this tutorial, we'll finally start using Async\/Await that'll make our code much nicer to look at!", 572 | "url": "https://www.youtube.com/watch?v=9tLA4r-gqds", 573 | "duration": "00:15:21" 574 | }, 575 | { 576 | "seqNo": 6, 577 | "title": "Express MongoDB REST API #6 - More Routes", 578 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/qAkzBQw_MrY\/default.jpg", 579 | "description": "In this video, we'll continue writing more routes as per our original endpoints spec.", 580 | "url": "https://www.youtube.com/watch?v=qAkzBQw_MrY", 581 | "duration": "00:15:12" 582 | }, 583 | { 584 | "seqNo": 7, 585 | "title": "Express MongoDB REST API #7 - Relationships", 586 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/FVn_wj1jLN0\/default.jpg", 587 | "description": "In this video, we'll wire up the necessary relationships between models in our routes logic.", 588 | "url": "https://www.youtube.com/watch?v=FVn_wj1jLN0", 589 | "duration": "00:22:49" 590 | }, 591 | { 592 | "seqNo": 8, 593 | "title": "Express MongoDB REST API #8 - Parameters Validation", 594 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/tJlmAAxwygc\/default.jpg", 595 | "description": "In this video, we'll set up the validation in our API. We won't just do it, but instead we'll create a function that'll allow us to validate any parameter we would need in future!", 596 | "url": "https://www.youtube.com/watch?v=tJlmAAxwygc", 597 | "duration": "00:30:59" 598 | }, 599 | { 600 | "seqNo": 9, 601 | "title": "Express MongoDB REST API #9 - Body Validation", 602 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/36v09ARHshc\/default.jpg", 603 | "description": "In this video, we'll continue where we left off. More precisely, we'll do the body validation this time and also use both the parameters and body validation functions that we wrote throughout our endpoints.", 604 | "url": "https://www.youtube.com/watch?v=36v09ARHshc", 605 | "duration": "00:24:46" 606 | }, 607 | { 608 | "seqNo": 10, 609 | "title": "Express MongoDB REST API #10 - Cars Routes Start", 610 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/-bQbI2rcoWI\/default.jpg", 611 | "description": "In this video, we'll begin our work on Cars resource. We'll start by defining routes and writing corresponding code in Cars controller. We'll also do the validation as we go.\n\nAt around ~17 minute mark my microphone started acting weirdly, so sorry for that. Had no idea about it until the video was finished.", 612 | "url": "https://www.youtube.com/watch?v=-bQbI2rcoWI", 613 | "duration": "00:22:29" 614 | }, 615 | { 616 | "seqNo": 11, 617 | "title": "Express MongoDB REST API #11 - Cars Routes End", 618 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/sA5yM3TALA4\/default.jpg", 619 | "description": "In this video, we'll finish our work on cars resource. We'll continue by defining routes until we're done. We'll also do the validation as we go.", 620 | "url": "https://www.youtube.com/watch?v=sA5yM3TALA4", 621 | "duration": "00:22:37" 622 | }, 623 | { 624 | "seqNo": 12, 625 | "title": "Express MongoDB REST API #12 - What to do next", 626 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/4A-Z7ts7dVg\/default.jpg", 627 | "description": "In this video, we finish this playlist and I talk a bit about security and what to do next.", 628 | "url": "https://www.youtube.com/watch?v=4A-Z7ts7dVg", 629 | "duration": "00:03:54" 630 | } 631 | ] 632 | }, 633 | { 634 | "id": 4, 635 | "description": "Advanced JavaScript", 636 | "url": "https://www.youtube.com/playlist?list=PLqrUy7kON1meuCvGp2D6yTglZhPTT_s_f", 637 | "longDescription": "", 638 | "iconUrl": "https://i.ytimg.com/vi/XskMWBXNbp0/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLCqe_0mn_r8odSitIcg8ManucWeQg", 639 | "seqNo": 3, 640 | "tags": "INTERMEDIATE", 641 | "channelTitle": "Tyler McGinnis", 642 | "channelUrl": "https://www.youtube.com/channel/UCbAn7pVK2VIyo-UysfWGdZQ", 643 | "channelId": "UCbAn7pVK2VIyo-UysfWGdZQ", 644 | "lessons": [ 645 | { 646 | "seqNo": 1, 647 | "title": "A Beginner's Guide to JavaScript's Prototype", 648 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/XskMWBXNbp0\/default.jpg", 649 | "description": "You can't get very far in JavaScript without dealing with objects. They're foundational to almost every aspect of the JavaScript programming language. In this post you'll learn about a variety of patterns for instantiating new objects and in doing so, you'll be gradually led to understanding JavaScript's prototype in depth.\n\nIt may seem surprising, but in my opinion the most important and fundamental concept to understanding the JavaScript language is understanding Execution Context. In this video you'll not only learn all about Execution Contexts, but also more advanced JavaScript topics like hoisting, the scope chain, and closures.\n\n\ud83d\ude80 Check out our \"Advanced JavaScript\" course for more detail on this and other JavaScript topics - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/?s=youtube-beginners-guide-to-javascripts-prototype\n\nIf you use JavaScript in any capacity, there\u2019s probably not another resource that will benefit you more than this. This course was years in the making. I took everything I know about JavaScript and all my experience teaching it over the last half decade and put it into this one course.\n\nWe\u2019ll cover topics like\n \u2705 Execution Contexts \n \u2705 Blocking vs Non Blocking IO \n \u2705 Scopes \n \u2705 The Scope Chain \n \u2705 The Event Loop \n \u2705 Closures \n \u2705 Hoisting \n \u2705 Instantiation Patterns\n \u2705 FN.prototype \n \u2705 this, .call, .apply, and .bind \n \u2705 IIFEs\/CommonJS\/ES Modules \n \u2705 Inheritance \n \u2705 Composition \n \u2705 Async Patterns\n\nAdvanced JavaScript - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\n\ud83d\udcfa Subscribe to our channel for more educational content to help you master the JavaScript ecosystem: https:\/\/www.youtube.com\/tylermcginnis\n\nTylerMcGinnis.com is a linear, project-based approach to mastering the JavaScript ecosystem. Our React courses have been taken by over 80k students with an average rating of 4.8\/5. So whether you want to learn more about React Hooks, React Native, React Router, vanilla JavaScript, or all of the above, our in-depth courses and tutorials will teach you everything you need to know about utilizing these technologies in 2019.\n\n\ud83c\udfc3 Visit our website for more in-depth, highly-rated educational content to help you master the JavaScript ecosystem: https:\/\/tylermcginnis.com\/", 650 | "url": "https://www.youtube.com/watch?v=XskMWBXNbp0", 651 | "duration": "00:28:23" 652 | }, 653 | { 654 | "seqNo": 2, 655 | "title": "The Ultimate Guide to Execution Contexts, Hoisting, Scopes, and Closures in JavaScript", 656 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/Nt-qa_LlUH0\/default.jpg", 657 | "description": "It may seem surprising, but in my opinion the most important and fundamental concept to understanding the JavaScript language is understanding Execution Context. In this video you'll not only learn all about Execution Contexts, but also more advanced JavaScript topics like hoisting, the scope chain, and closures.\n\nIt may seem surprising, but in my opinion the most important and fundamental concept to understanding the JavaScript language is understanding Execution Context. In this video you'll not only learn all about Execution Contexts, but also more advanced JavaScript topics like hoisting, the scope chain, and closures.\n\n\ud83d\ude80 Check out our \"Advanced JavaScript\" course for more detail on this and other JavaScript topics - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/?s=youtube-ultimate-guide-to-hoisting-scopes-closures-in-javascript\n\nIf you use JavaScript in any capacity, there\u2019s probably not another resource that will benefit you more than this. This course was years in the making. I took everything I know about JavaScript and all my experience teaching it over the last half decade and put it into this one course.\n\nWe\u2019ll cover topics like\n \u2705 Execution Contexts \n \u2705 Blocking vs Non Blocking IO \n \u2705 Scopes \n \u2705 The Scope Chain \n \u2705 The Event Loop \n \u2705 Closures \n \u2705 Hoisting \n \u2705 Instantiation Patterns\n \u2705 FN.prototype \n \u2705 this, .call, .apply, and .bind \n \u2705 IIFEs\/CommonJS\/ES Modules \n \u2705 Inheritance \n \u2705 Composition \n \u2705 Async Patterns\n\nAdvanced JavaScript - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\n\ud83d\udcfa Subscribe to our channel for more educational content to help you master the JavaScript ecosystem: https:\/\/www.youtube.com\/tylermcginnis\n\nTylerMcGinnis.com is a linear, project-based approach to mastering the JavaScript ecosystem. Our React courses have been taken by over 80k students with an average rating of 4.8\/5. So whether you want to learn more about React Hooks, React Native, React Router, vanilla JavaScript, or all of the above, our in-depth courses and tutorials will teach you everything you need to know about utilizing these technologies in 2019.\n\n\ud83c\udfc3 Visit our website for more in-depth, highly-rated educational content to help you master the JavaScript ecosystem: https:\/\/tylermcginnis.com\/", 658 | "url": "https://www.youtube.com/watch?v=Nt-qa_LlUH0", 659 | "duration": "00:25:35" 660 | }, 661 | { 662 | "seqNo": 3, 663 | "title": "The Evolution of Async JavaScript: From Callbacks, to Promises, to Async\/Await", 664 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/gB-OmN1egV8\/default.jpg", 665 | "description": "In this video you'll learn about the historical context as well as the pros and cons behind the three most popular JavaScript async patterns - Callbacks, Promises, and Async\/Await.\n\n\ud83d\ude80 Check out our \"Advanced JavaScript\" course for more detail on this and other JavaScript topics - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/?s=youtube-async-javascript-callbacks-promises-async-await\n\nIf you use JavaScript in any capacity, there\u2019s probably not another resource that will benefit you more than this. This course was years in the making. I took everything I know about JavaScript and all my experience teaching it over the last half decade and put it into this one course.\n\nWe\u2019ll cover topics like\n \u2705 Execution Contexts \n \u2705 Blocking vs Non Blocking IO \n \u2705 Scopes \n \u2705 The Scope Chain \n \u2705 The Event Loop \n \u2705 Closures \n \u2705 Hoisting \n \u2705 Instantiation Patterns\n \u2705 FN.prototype \n \u2705 this, .call, .apply, and .bind \n \u2705 IIFEs\/CommonJS\/ES Modules \n \u2705 Inheritance \n \u2705 Composition \n \u2705 Async Patterns\n\nAdvanced JavaScript - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\n\ud83d\udcfa Subscribe to our channel for more educational content to help you master the JavaScript ecosystem: https:\/\/www.youtube.com\/tylermcginnis\n\nTylerMcGinnis.com is a linear, project-based approach to mastering the JavaScript ecosystem. Our React courses have been taken by over 80k students with an average rating of 4.8\/5. So whether you want to learn more about React Hooks, React Native, React Router, vanilla JavaScript, or all of the above, our in-depth courses and tutorials will teach you everything you need to know about utilizing these technologies in 2019.\n\n\ud83c\udfc3 Visit our website for more in-depth, highly-rated educational content to help you master the JavaScript ecosystem: https:\/\/tylermcginnis.com\/", 666 | "url": "https://www.youtube.com/watch?v=gB-OmN1egV8", 667 | "duration": "00:45:25" 668 | }, 669 | { 670 | "seqNo": 4, 671 | "title": "JavaScript Private and Public Class Fields", 672 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/ZxpdR_C7RVA\/default.jpg", 673 | "description": "ES6 classes were introduced just a few years ago but because this is JavaScript, there's already a stage 3 proposal to make the API more enjoyable. In this video we're going to go over what those changes are and some misconceptions regarding them.\n\n\ud83d\ude80 Check out our \"Advanced JavaScript\" course for more detail on this and other JavaScript topics - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/?s=javascript-private-public-class-fields\n\nI\u2019m not good at writing sales copy, so just trust me that if you use JavaScript in any capacity, there\u2019s probably not another resource that will benefit you more than this. This course was years in the making. I took everything I know about JavaScript and all my experience teaching it over the last half decade and put it into this one course.\n\nWe\u2019ll cover topics like\n \u2705 Execution Contexts \n \u2705 Blocking vs Non Blocking IO \n \u2705 Scopes \n \u2705 The Scope Chain \n \u2705 The Event Loop \n \u2705 Closures \n \u2705 Hoisting \n \u2705 Instantiation Patterns\n \u2705 FN.prototype \n \u2705 this, .call, .apply, and .bind \n \u2705 IIFEs\/CommonJS\/ES Modules \n \u2705 Inheritance \n \u2705 Composition \n \u2705 Async Patterns\n\nAdvanced JavaScript - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\n\ud83d\udcfa Subscribe to our channel for more educational content to help you master the JavaScript ecosystem: https:\/\/www.youtube.com\/tylermcginnis\n\nTylerMcGinnis.com is a linear, project-based approach to mastering the JavaScript ecosystem. Our React courses have been taken by over 80k students with an average rating of 4.8\/5. So whether you want to learn more about React Hooks, React Native, React Router, vanilla JavaScript, or all of the above, our in-depth courses and tutorials will teach you everything you need to know about utilizing these technologies in 2019.\n\n\ud83c\udfc3 Visit our website for more in-depth, highly-rated educational content to help you master the JavaScript ecosystem: https:\/\/tylermcginnis.com\/", 674 | "url": "https://www.youtube.com/watch?v=ZxpdR_C7RVA", 675 | "duration": "00:08:30" 676 | }, 677 | { 678 | "seqNo": 5, 679 | "title": "JavaScript Inheritance and the Prototype Chain", 680 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/MiKdRJc4ooE\/default.jpg", 681 | "description": "Inheritance is a principle of Object Oriented Programming. In this post you'll learn how to accomplish inheritance in JavaScript in both ES5 as well as ES6.\n\n\ud83d\ude80 Check out our \"Advanced JavaScript\" course for more detail on this and other JavaScript topics - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/?s=youtube-javascript-inheritance-prototype-chain\n\nI\u2019m not good at writing sales copy, so just trust me that if you use JavaScript in any capacity, there\u2019s probably not another resource that will benefit you more than this. This course was years in the making. I took everything I know about JavaScript and all my experience teaching it over the last half decade and put it into this one course.\n\nWe\u2019ll cover topics like\n \u2705 Execution Contexts \n \u2705 Blocking vs Non Blocking IO \n \u2705 Scopes \n \u2705 The Scope Chain \n \u2705 The Event Loop \n \u2705 Closures \n \u2705 Hoisting \n \u2705 Instantiation Patterns\n \u2705 FN.prototype \n \u2705 this, .call, .apply, and .bind \n \u2705 IIFEs\/CommonJS\/ES Modules \n \u2705 Inheritance \n \u2705 Composition \n \u2705 Async Patterns\n\nAdvanced JavaScript - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\n\ud83d\udcfa Subscribe to our channel for more educational content to help you master the JavaScript ecosystem: https:\/\/www.youtube.com\/tylermcginnis\n\nTylerMcGinnis.com is a linear, project-based approach to mastering the JavaScript ecosystem. Our React courses have been taken by over 80k students with an average rating of 4.8\/5. So whether you want to learn more about React Hooks, React Native, React Router, vanilla JavaScript, or all of the above, our in-depth courses and tutorials will teach you everything you need to know about utilizing these technologies in 2019.\n\n\ud83c\udfc3 Visit our website for more in-depth, highly-rated educational content to help you master the JavaScript ecosystem: https:\/\/tylermcginnis.com\/\n\nYou can find the full blog post here - \nhttps:\/\/tylermcginnis.com\/javascript-inheritance-and-the-prototype-chain\/", 682 | "url": "https://www.youtube.com/watch?v=MiKdRJc4ooE", 683 | "duration": "00:13:55" 684 | }, 685 | { 686 | "seqNo": 6, 687 | "title": "JavaScript Composition vs Inheritance", 688 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/7HolHe7Gqbw\/default.jpg", 689 | "description": "You've probably heard that you should favor composition over inheritance. This post breaks down why that is by looking at where inheritance breaks down and composition shines.\n\n\ud83d\ude80 Check out our \"Advanced JavaScript\" course for greater detail on this and other JavaScript topics - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/?s=youtube-javascript-inheritance-vs-composition\n\nI\u2019m not good at writing sales copy, so just trust me that if you use JavaScript in any capacity, there\u2019s probably not another resource that will benefit you more than this. This course was years in the making. I took everything I know about JavaScript and all my experience teaching it over the last half decade and put it into this one course.\n\nWe\u2019ll cover topics like\n \u2705 Execution Contexts \n \u2705 Blocking vs Non Blocking IO \n \u2705 Scopes \n \u2705 The Scope Chain \n \u2705 The Event Loop \n \u2705 Closures \n \u2705 Hoisting \n \u2705 Instantiation Patterns\n \u2705 FN.prototype \n \u2705 this, .call, .apply, and .bind \n \u2705 IIFEs\/CommonJS\/ES Modules \n \u2705 Inheritance \n \u2705 Composition \n \u2705 Async Patterns\n\nAdvanced JavaScript - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\n\ud83d\udcfa Subscribe to our channel for more educational content to help you master the JavaScript ecosystem: https:\/\/www.youtube.com\/tylermcginnis\n\nTylerMcGinnis.com is a linear, project-based approach to mastering the JavaScript ecosystem. Our React courses have been taken by over 80k students with an average rating of 4.8\/5. So whether you want to learn more about React Hooks, React Native, React Router, vanilla JavaScript, or all of the above, our in-depth courses and tutorials will teach you everything you need to know about utilizing these technologies in 2019.\n\n\ud83c\udfc3 Visit our website for more in-depth, highly-rated educational content to help you master the JavaScript ecosystem: https:\/\/tylermcginnis.com\/", 690 | "url": "https://www.youtube.com/watch?v=7HolHe7Gqbw", 691 | "duration": "00:06:16" 692 | }, 693 | { 694 | "seqNo": 7, 695 | "title": "Creating your own JavaScript Array", 696 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/YliiOCGNfns\/default.jpg", 697 | "description": "This video walks you through how to recreate the basic functionality of a JavaScript array, enabling you to explore certain patterns and features of the JavaScript language in a practical exercise.\n\n\ud83d\ude80 Check out our \"Advanced JavaScript\" course for greater detail on this and other JavaScript topics - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/?s=youtube-creating-your-own-implementation-of-array\n \nI\u2019m not good at writing sales copy, so just trust me that if you use JavaScript in any capacity, there\u2019s probably not another resource that will benefit you more than this. This course was years in the making. I took everything I know about JavaScript and all my experience teaching it over the last half decade and put it into this one course.\n\nWe\u2019ll cover topics like\n \u2705 Execution Contexts \n \u2705 Blocking vs Non Blocking IO \n \u2705 Scopes \n \u2705 The Scope Chain \n \u2705 The Event Loop \n \u2705 Closures \n \u2705 Hoisting \n \u2705 Instantiation Patterns\n \u2705 FN.prototype \n \u2705 this, .call, .apply, and .bind \n \u2705 IIFEs\/CommonJS\/ES Modules \n \u2705 Inheritance \n \u2705 Composition \n \u2705 Async Patterns\n\nAdvanced JavaScript - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\n\ud83d\udcfa Subscribe to our channel for more educational content to help you master the JavaScript ecosystem: https:\/\/www.youtube.com\/tylermcginnis\n\nTylerMcGinnis.com is a linear, project-based approach to mastering the JavaScript ecosystem. Our React courses have been taken by over 80k students with an average rating of 4.8\/5. So whether you want to learn more about React Hooks, React Native, React Router, vanilla JavaScript, or all of the above, our in-depth courses and tutorials will teach you everything you need to know about utilizing these technologies in 2019.\n\n\ud83c\udfc3 Visit our website for more in-depth, highly-rated educational content to help you master the JavaScript ecosystem: https:\/\/tylermcginnis.com\/", 698 | "url": "https://www.youtube.com/watch?v=YliiOCGNfns", 699 | "duration": "00:12:32" 700 | }, 701 | { 702 | "seqNo": 8, 703 | "title": "JavaScript Modules: From IIFEs to CommonJS to ES6 Modules", 704 | "thumbnailUrl": "https:\/\/i.ytimg.com\/vi\/qJWALEoGge4\/default.jpg", 705 | "description": "Consistently the most commonly under-learned aspect of JavaScript is the module system. There's good reason for that. Modules in JavaScript have a strange and erratic history. In this post we'll walk through that history, and you'll learn modules of the past to better understand how JavaScript modules work today. \n\n\ud83d\ude80 Check out our \"Advanced JavaScript\" course for greater detail on this and other JavaScript topics: https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\nI\u2019m not good at writing sales copy, so just trust me that if you use JavaScript in any capacity, there\u2019s probably not another resource that will benefit you more than this. This course was years in the making. I took everything I know about JavaScript and all my experience teaching it over the last half decade and put it into this one course.\n\nWe\u2019ll cover topics like\n \u2705 Execution Contexts \n \u2705 Blocking vs Non Blocking IO \n \u2705 Scopes \n \u2705 The Scope Chain \n \u2705 The Event Loop \n \u2705 Closures \n \u2705 Hoisting \n \u2705 Instantiation Patterns\n \u2705 FN.prototype \n \u2705 this, .call, .apply, and .bind \n \u2705 IIFEs\/CommonJS\/ES Modules \n \u2705 Inheritance \n \u2705 Composition \n \u2705 Async Patterns\n\nAdvanced JavaScript Course - https:\/\/tylermcginnis.com\/courses\/advanced-javascript\/\n\n\ud83d\udcfa Subscribe to our channel for more educational content to help you master the JavaScript ecosystem: https:\/\/www.youtube.com\/tylermcginnis\n\nHere's the full blog post - https:\/\/tylermcginnis.com\/javascript-modules\n\nTylerMcGinnis.com is a linear, project-based approach to mastering the JavaScript ecosystem. Our React courses have been taken by over 80k students with an average rating of 4.8\/5. So whether you want to learn more about React Hooks, React Native, React Router, vanilla JavaScript, or all of the above, our in-depth courses and tutorials will teach you everything you need to know about utilizing these technologies in 2019.\n\n\ud83c\udfc3 Visit our website for more in-depth, highly-rated educational content to help you master the JavaScript ecosystem: https:\/\/tylermcginnis.com\/", 706 | "url": "https://www.youtube.com/watch?v=qJWALEoGge4", 707 | "duration": "00:32:14" 708 | } 709 | ] 710 | } 711 | ] 712 | --------------------------------------------------------------------------------