Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Your project this week is to build a frontend for one of the APIs from REST API week. It should be a single-page app rendered with client-side JavaScript.
If your team don't have a finished API, or don't want to use it, you can use the Dogs API from the workshops. The readme contains documentation of all the endpoints.
As a user, I want to: see all the resources
As a user, I want to: sign up for an account
As a user, I want to: log in to my account
As a user, I want to: add my own resources
As a user, I want to: update my own resources
As a user, I want to: delete my own resources
Since this project is open-ended you'll need to write your own more specific user stories once you know what you want to build.
There's a lot more to React than we could cover in a week. It's worth reading through the official docs to reinforce your learning and learn more interesting new features. The links below are the most important concepts you should cover.
Your project this week is to build anything you like as long as it meets the technical criteria below. It should still be a Node/Express server-rendered application with a SQLite database, but feel free to get creative with the ideas.
This week is the culmination of your Express learning, so focus on doing everything as professionally as you can. Your app should have validation, error-handling, good user-experience etc.
Your project should include at least one of these new topics. You'll have to spend some time researching them in your group, figuring out how exactly to implement them before you start working on your project. There are minimal examples provided, but they are only one way to approach it—you should look for tutorials/blog posts etc with alternative solutions and find one you like.
Allow users to upload files to your server (like images or audio clips). View file upload example | View code
Allow users to log in using 3rd party accounts like Google or GitHub. View GitHub login example | View code
Show temporary messages after successful/failed form submissions to help the user understand what's happening. Note that this is a little complex to manage on your own: you may want to use a session middleware library from npm. View flash message example | View code
Your project this week is to build a microblogging site. It should allow users to submit their own posts and view all the posts submitted by others.
Note: we aren't expecting the data to persist when the server restarts (we'll be looking at databases for this next week).
Before you start implementing features you need to figure out how to deploy a Node app to Fly.io.
Fly is a "Platform-as-a-service" provider (PaaS). PaaS is a type of cloud computing service that provides users with a platform for deploying and managing apps. They provide a convenient way for developers to quickly get their apps up and running without having to worry about the technical details of the infrastructure and resources they need.
What are environment variables and why might we want to hide them?
How can we automatically deploy commits to our main
branch?
Deploying web apps to Fly.io (you don't need to worry about the "Persistent Volumes" section for this week's spike)
As an opinionated person, I want to: post my thoughts so others can read them
As a bored person, I want to: read what other people have posted
As an impulsive person, I want to: delete my posts so no one can see them anymore
These resources are helpful extra reading that may clarify or enhance concepts you're learning in the main curriculum.
Official counterpart to the Node docs. Useful for getting realistic examples of features when the docs are overwhelming and confusing.
Popular (if slightly outdated) overview of what Node is and how it works.
General background info on how servers work
Gatsby is a React-based open source framework for creating websites. They provide an outline continuous deployment.
This week is the first build sprint of your in-house project build.
Work through your sprint backlog, assigning user stories to members of the team.
How do web applications store and retrieve vast amounts of information? How does an e-commerce website keep track of its products and inventory? Or how does a social media platform manage user profiles and posts? The answer lies in databases. Here, we'll introduce you to the concept of databases and explain their role in web development.
At its core, a database is a structured collection of information. The term "structured" implies that the data can be easily organised and queried by a computer. This is opposed to for example a paragraph in a book that can contain data but lacks structure.
To better grasp structured data, here are a few examples:
HTML table: Structured data as it organises information into rows and columns, making it easy to access and present.
JSON object: Structured data format for exchanging information between servers and web applications, following a specific syntax of key-value pairs or arrays.
Spreadsheet: Structured data tool that organises information into rows and columns, allowing for efficient data organisation and analysis.
Computers have two primary forms of storage: memory (RAM) and disk storage. Memory allows a computer to store and quickly access data that it actively uses. However, memory is relatively expensive and limited, typically ranging from 8 to 16 gigabytes in modern computers. On the other hand, disk storage, though slower, is more cost-effective and offers larger capacities, typically reaching hundreds of gigabytes.
In the early days of computing, memory was extremely expensive, leading to the development of databases optimised for memory usage. These databases are known as "relational" databases. They store data in tables, resembling spreadsheets, and allow efficient data access.
For instance, consider a table named "fruits" that contains information about fruit names, quantities, and prices:
To establish relationships between different tables, relational databases introduce the concept of "foreign keys." Suppose we have another table named "stores" that includes store locations and IDs:
By adding a foreign key, such as the "store_id" column, to the "fruits" table, we can relate each fruit entry to a specific store:
This relational structure minimises data duplication and allows us to determine which store offers which fruit at what price easily.
The relational database structure offers several advantages. Firstly, it reduces data duplication, as each store is listed only once, regardless of the number of fruits they have. Comparatively, representing the same information using objects would result in duplicated store details within each fruit object.
Consider the following JSON representation:
In a database with thousands of entries, this approach would result in significant duplication. By employing relational databases, we save storage space and ensure data consistency.
Secondly, relational databases simplify answering certain types of questions. For example, determining the total quantity of fruit requires adding up the "quantity" column, without the need to consider the associated stores. Relational databases enable efficient querying and data analysis.
Several popular relational databases are widely used in web development, including MySQL, PostgreSQL, and SQLite. They offer robust features, performance, and compatibility with various programming languages.
To interact with a relational database, developers use Structured Query Language (SQL). SQL is a specialised language for retrieving and manipulating data in a relational database. For example, the following SQL query retrieves the "name" and "quantity" columns from the "fruits" table:
SQL empowers developers to extract information from the database and perform complex operations using a standardised syntax.
As computer memory became cheaper, alternative database solutions emerged. These databases utilised less structured data storage approaches, such as objects. While they might be less efficient in terms of storage utilisation, they offered faster data retrieval by keeping everything in memory. These databases were dubbed "NoSQL" databases due to their lack of support for SQL.
MongoDB and CouchDB are examples of popular NoSQL databases. Developers often prefer NoSQL databases when the object-oriented paradigm aligns better with their mental model and the requirements of their projects. However, for most web development scenarios, relational databases remain the safer and more versatile choice.
We’ll be using SQLite as our relational database. SQLite is lightweight, easy to set up, and provides a smooth learning experience.
Relational databases excel at managing three main types of relationships: one-to-one, one-to-many, and many-to-many.
One-to-one relationship: In this type, each entity in one table corresponds to exactly one entity in another table. For example, each country has one capital city, and each capital city belongs to one country.
Tables
countries
cities
We use a “foreign key” to create relationships.
The capital_id
column in countries
represents a row in cities
.
One-to-many relationship: This relationship exists when each entity in one table is associated with multiple entities in another table, but each entity in the second table corresponds to only one entity in the first table. For instance, a director can create multiple films, while each film has only one director.
Tables
directors
films
The only difference here is the foreign keys aren’t unique.
We represent the “many” relationship by using the same director_id
for multiple films.
Many-to-many relationship: This relationship occurs when multiple entities in one table are associated with multiple entities in another table. A classic example is the relationship between actors and films. An actor can appear in many films, and a film can include multiple actors.
Tables
actors
films
actors_films (join table)
We cannot use foreign keys here since each film would need multiple actor_id
columns. Instead we can use another table to store the relationships.
In a many-to-many relationship, a join table bridges the gap between the two related tables. By using the join table "actors_films," we can associate actors with the films they appear in. This allows us to look up an actor's films efficiently.
For example, the following SQL query retrieves the names of actors and the names of films they appear in:
In conclusion, relational databases offer powerful features, minimise data duplication, and allow for complex querying using SQL. While non-relational databases offer flexibility and speed, relational databases remain the go-to choice for most web development scenarios.
There are no defined spikes for this week.
You're encouraged to continue role circles with those who are playing the same role as you.
name | quantity | price |
---|---|---|
id | location |
---|---|
name | quantity | price | store_id |
---|---|---|---|
id | name | capital_id |
---|---|---|
id | name | population |
---|---|---|
id | name |
---|---|
id | name | director_id |
---|---|---|
id | name |
---|---|
id | name |
---|---|
actor_id | film_id |
---|---|
You may find that you need to manage spikes within your sprints. Remember to follow .
apple
10
1.00
banana
20
0.40
1
camden
2
kensington
apple
10
1.00
1
banana
20
0.40
1
apple
05
1.20
2
banana
30
0.20
2
1
uk
1
2
usa
2
1
london
8.9m
2
washington dc
0.7m
1
Olivia Wilde
2
Sofia Coppola
1
booksmart
1
2
lost in translation
2
3
the bling ring
2
1
Cate Blanchett
2
Ian McKellan
1
LOTR: The Fellowship of the Ring
2
X-Men
3
Ocean's 8
1
1
1
3
2
1
2
2
There are no defined spikes for this week.
You may find that you need to manage spikes within your sprints. Remember to follow the techniques you followed earlier in the programme.
You're encouraged to continue role circles with those who are playing the same role as you.
This week is the first build sprint of your in-house project build.
Work through your sprint backlog, assigning user stories to members of the team.
This week, spikes will be in your project groups.
Use this as an opportunity to read and explore documentation on a new technology that you might need for your project, or to find a definitive answer for some of the "How might we" questions that came up during the definition workshop.
If you are looking into new tech, here's a checklist to keep in mind during your research.
List out your needs, and compare them to a list of the pros and cons of the technology you're looking at.
How popular is it? How well maintained is it?
How good is the documentation? What is the learning curve compared to things you have already used?
Are there good external learning resources? (look into different media types - eg: video)
How much time would go into learning vs implementing?
Does it require payment/ does it have limits on usage that would hinder your project?
Take ideas from your Definition workshop and the sketches you did there. You can consider the ideas you came up with there as low-fidelity prototypes and with Figma, you'll create a high-fidelity prototype.
Your wireframe should include the main steps of the user journey. Think about which parts of the journey you'd like to get feedback on from your users and prioritise building these.
Your project in Design Week is to create a wireframe in and test it with your Product Owners' user group.
There are no defined spikes for this week.
You may find that you need to manage spikes within your sprints. Remember to follow the techniques you followed earlier in the programme.
You're encouraged to continue role circles with those who are playing the same role as you.
This week is the first build sprint of your in-house project build.
Work through your sprint backlog, assigning user stories to members of the team.
Your project this week is to build a web app that authenticates users and stores user-specific data in a SQLite database.
Before you start writing features you need to create a security plan. This should a section in your README.md
that describes how you will secure your app and mitigate different potential attacks.
Will you store session info in a cookie (stateless) or in your database (stateful)?
How will you check a user's identity (authentication)?
How will you control what actions a user can take (authorization)?
How will you mitigate Cross-site Request Forgery (CSRF) attacks?
As a user, I want to: submit information to your site for anyone to see
As a user, I want to: come back to your site later and see what I posted is still there
As a user, I want to: be the only person allowed to delete my stuff
Since this project is open-ended you'll need to write your own more specific user stories once you know what you want to build.
Founders & Coders book sharing system
Food / coffee recommendations around Founders & Coders
Founders & Coders events calendar
Time | Activity | Learning outcomes |
---|
Time | Activity | Learning outcomes |
---|
Time | Activity | Learning outcomes |
---|
Time | Activity |
---|
Time | Activity |
---|
09:45 | Check-in |
10:00 | Project |
13:00 | Lunch |
14:00 | Project |
17:45 | Check out |
09:45 | Check-in |
10:00 | Team code review |
10:45 | Expert Feedback - Live code review |
11:15 | Respond to issues |
12:00 | Role circles |
12:15 | Presentation prep |
13:00 | Lunch |
14:00 | Presentations |
15:15 | Cohort SGC |
16:00 | Team SGC |
16:45 | Update user manuals |
17:00 | Speaker |
17:45 | Check out |
How can we modularise our client-side JavaScript?
What are the different ways we can import/export code? What does "dynamic import" do?
Why might using hundreds of small modules in the browser cause performance problems?
What is the "critical rendering path" in browsers?
How does the browser render an HTML page containing links to CSS and JavaScript files?
What does "render blocking" mean?
What do the async
and defer
keywords do?
How can we avoid unnecessary network requests?
What is HTTP caching?
How can our server tell browsers to cache our responses?
How we can efficiently serve image assets?
How can we optimise image file size?
How can we render different images at different viewport sizes?
09:45 | Check-in |
10:00 |
10:30 | Native JS modules |
11:00 | innerHTML, Template element |
13:00 | Lunch |
14:00 | Components, Stateful rendering |
16:00 |
16:15 |
17:15 | Spike presentation prep |
17:45 | Checkout |
09:45 | Check-in |
10:00 | Spike presentation prep |
10:10 | Spike presentations |
11:00 | localStorage, token auth |
13:00 | Lunch |
14:00 | Student project session |
14:30 | live regions, status updates |
16:00 | Tech for Better |
17:00 | Speaker |
17:45 | Check out |
09:45 | Check-in |
10:00 | CSS pseudo-elements |
11:00 | Project |
12:45 | Role circles |
13:00 | Lunch |
16:30 |
17:00 | Tech for Better |
17:45 | Check out |
These resources are helpful extra reading that may clarify or enhance concepts you're learning in the main curriculum.
Despite the title this talk actually covers most aspects of web authentication in a very accessible way
How to work with cookies while you are developing
The 8 Principles of Secure Development & Deployment set out by the National Cyber Security Center
Web applications are an amalgamation of data and markup. Let's consider a personal landing page as an example. The data comprises the specific information about you, while the markup is the HTML that encapsulates this information.
There are generally two types of data we work with - static and dynamic. Static data doesn't undergo much change, enabling you to craft the HTML in advance. The server, yours or a third-party service like Netlify's, just responds with the pre-generated static .html
file when a request is made.
On the contrary, dynamic data changes with each request. With such data, you are required to generate each page on demand. This page generation can occur either on the server or the client.
Generating pages on the server is usually simpler and safer, but doing it on the client allows for more dynamic interaction. What if there was a way to do both, within the same application?
Next.js is a powerful framework for building websites using React. React, although an excellent library for building user interfaces, doesn't provide many necessities for websites such as routing, server-rendering, and data fetching. Next.js steps in to fill these gaps, creating "isomorphic" JavaScript applications that render both on the server and the client.
This dual-rendering process works as follows: initially, the page load is server-rendered HTML. Once the JavaScript loads, the whole application runs client-side. This balance is a compromise between initial performance (showing HTML quickly) and later interactivity on the client side.
To use Next.js, you create React components in a pages/
directory. Here's an example:
Next.js's Node server creates a route for this component:
The server initially renders your application to get the HTML. Then it renders your app again on the client to "hydrate" it. The hydration process instructs React to connect to existing DOM nodes.
Before hydration happens, the user can still see the HTML. Once hydration finishes, you have a fully functioning client-side app.
In addition to managing front-end rendering, Next.js also supports "API routes". These are routes that don't render React components but return JSON instead.
To implement this, you create files inside pages/api/
. These files are used as handlers for the matching route. For instance:
This enables you to build an API route that fetches JSON data, which is simpler than having to create and deploy a whole separate server.
In conclusion, Next.js presents an efficient way to develop full-stack applications, providing out-of-the-box solutions for some of the most common web development needs, all while leveraging the power of React. It offers an excellent bridge between server-side rendering for optimal performance and client-side rendering for dynamic interactivity.
These resources are helpful extra reading that may clarify or enhance concepts you're learning in the main curriculum.
A graphical interface for viewing and editing your database
W3Schools have lots of clear simple example for different types of SQL queries
Amazing summary of the history of databases, what they are, how they work and the different types
Summary of one of the most common ways web apps get hacked
An example of how you might structure a project using Express & SQlite
5 Critical Differences
Your project this week is to build an interactive game-like thing using React.
"Interactive game-like thing" is a bit vague, so here are some apps built previously:
If you're struggling for inspiration consider adapting a simple board/card/arcade game that you like.
npm create vite myapp -- --template react
cd myapp
npm install
to install the dependencies
npm run dev
start the dev server
Open the project in your editor—you should see an example app. Feel free to delete the logo/CSS files that you won't be using.
CSS files will automatically be copied to the final built site and included on the page. Images and other assets will provide the URL of the final asset to use in your components.
We strongly recommend you configure ESLint. This will help catch mistakes as you're coding and save you time debugging problems caused by simple typos.
Create your repo and push it to GitHub
Go to https://app.netlify.com and login with Github
Click the "New site from Git" button
Choose "Github" as your provider (and authorize it)
Choose the repo you want to deploy
Choose "Deploy site" (the build settings should be pre-filled)
Now every time you push to the main
branch your site will redeploy.
That said, if you have a token you want to keep off GitHub, but don't mind people potentially finding using dev tools (i.e. not a token attached to your credit card!) you can use a .env.local
file.
You can access that using import.meta.env.VITE_APP_API_KEY
.
Vite also generates a .gitignore
that stops .local
files from ending up on GitHub.
You will also need to configure Netlify to inject this value when it deploys your site too (just like Heroku). You can do this under "Site settings" > "Build & deploy" > "Environment" > "Environment variables".
and intro
Now that you're using a framework there is a bit more initial environment setup involved before you can start writing code. Make sure you get this done and to Netlify at the beginning.
We'll be using to handle bundling our app and providing a local dev server. You can quickly scaffold a new app using their CLI:
Vite supports (like images or CSS). For example:
You can use Oli's (follow the instructions in the readme to install).
We'll be deploying our apps to .
Vite will prefixed with VITE_
and make them available to your code on import.meta.env
. E.g. if you have a .env.local
file like this:
See week 1 for the learnings relating to the server topic.
There is no project during Introduction Week. See Week 1 for the project relating to the server topic.
This week you'll be building an e-commerce shopping site for a fake brand. It doesn't need to actually take payments or have a checkout, but it should have product listings.
Here's a very polished example (with more features than you need to implement): https://demo.vercel.store/
Server-rendered with Next.js
Homepage with product listings
Individual product pages, containing quantity/colour/variant pickers
Data stored in a SQLite database
"Add to basket" button on product pages
Basket page showing all saved items
Basket contents persisted for future visits (cookies or local storage)
Filter products by category
Sort products by price
End-to-end tests
It's important to get your project setup done as early as possible, so your team have a stable base to build on. You should follow this list as a team, before you do any other work on the project.
Generate a Next app with:
This command will scaffold a basic starting app structure in a new directory. You can cd
in and run npm run dev
to see what you've got.
Since version 11 Next has ESLint built in. Make sure you have an npm script to run it:
When you run this script for the first time it'll ask you what config you want to use.
If you have the ESLint VS Code extension installed you should also see errors highlighted in your editor.
It's important for your code to be formatted consistently across the project, regardless of who wrote it. Prettier helps with this by automating all formatting to one style.
You can rely on the Prettier VS Code extension to auto-format when you save. However you should make sure to include a Prettier config file in your project, otherwise each team member's extension will format according to their personal settings.
Create a .prettierrc
file at the root of your project:
An empty config will make Prettier use the default rules. If you want to customise any of them you can do so here. E.g.
You can follow Next's guide to testing with Playwright if you want to experiment with end-to-end tests.
Your project this week is to build a web app that stores data in a SQLite database.
Before you start writing features you need to design the schema for your data. Think about what different things your app needs to store, how they relate to each other, and how you can avoid duplicating information. Record your schema in your README.md
using Markdown tables. Consider embedding a diagram to help visualise the relationships.
What kinds of data relationships are there?
What's a foreign key? How can they help us design schemas with relational data?
As a user, I want to: submit information to your site for anyone to see
As a user, I want to: come back to your site later and see what I posted is still there
Since this project is open-ended you'll need to write your own more specific user stories once you know what you want to build.
Founders & Coders book sharing system
Food / coffee recommendations around Founders & Coders
Founders & Coders events calendar
A simple mental model for app deployment is that we’re installing and running our app on a computer in the cloud. Yet this is an oversimplification and an important difference is that the PaaS services we use for deployment (ie Fly) have an ephemeral file system.
An ephemeral file system is a type of file system that is not permanently stored on a device or disk. It exists only for a short period of time, and any files or data stored in it are not persisted after the session ends or the file system is deleted. This type of file system is usually used in cloud computing environment as it allows for greater flexibility and efficiency compared to using permanent storage.
As Fly uses an ephemeral file system and SQLite works by storing the database as a file on the system we need to make special provisions for deployment. If we didn’t, then our database would disappear every time the file system is restarted.
To solve this we’re going to use Fly’s Volume’s feature.
Install the Fly CLI and deploy your app if you haven’t already.
Create a volume by running the following command
flyctl volumes create data --region lhr --size 1
This will create a 1GB volume for the app whose fly.toml
is in the current directory.
You can think of a volume as being like an external hard drive that we get to use with our app.
You can use the volume you just created in your app by adding it to the fly.toml
:
This will tell us the directory under which this volume can be used, i.e. the volume data
that we created in the last step will be available on the path /data
when our app runs on Fly.io
's servers.
Now we have to deploy again so that the app knows about our updated fly.toml
file
flyctl deploy
The last step is to set the environment variable which we use in the our app (i.e. in database/db.js
). On fly, this needs to point to the directory we referenced in our fly.toml
file (ie data/
)
flyctl secrets set DB_FILE=/data/db.sqlite
We might also want to seed our database with initial data in our deployment environment. When we do this locally we usually run a command on the terminal which calls a script to insert the data, e.g. node src/database/seed.js
.
We’re going to do something similar to seed the remote data, but instead of running a command on our local terminal, we’re going to connect to the virtual machine that Fly has spun up for our app and run a command on that virtual machine’s terminal.
Before we connecting to the virtual machine, we'll need to add the volta
key to our package.json
. Volta is the tool that Fly uses to manage node versions.
Let's add the following to our package.json
(making sure that the node version you specify is the same one as in the generated Dockerfile
)
Then run flyctl deploy
to get these changes onto our deployed app.
To connect to the remote virtual machine we run the following command. SSH stands for Secure Shell and is a way to securely connect to another computer over a network.
flyctl ssh console
Once you’ve connected to the terminal you can find your files in the app/
directory and from there you can run your script.
cd app
node src/database/seed.js
Your database should now be seeded and you can check this by going to the URL for your deployed app and checking the data is there.
Web development has evolved dramatically over the years, and one of the pivotal aspects that have grown with it is authentication. Authentication plays a significant role in the modern web, ensuring that users are who they claim to be.
Most websites need a way to verify who is making requests. Generally this involves providing some secret only the user could know: often called a password.
This is fine as a one-off, but websites need to keep users logged in. You could ask the user to provide their password on every request. This would be a terrible user experience though.
A challenge arises because HTTP, the protocol that underlies the web, is inherently stateless. This means that each HTTP request knows nothing about previous or future requests. With this limitation, there was a need for a mechanism to maintain continuity and remember users across requests. Enter "cookies".
Invented in 1994, cookies were designed to preserve state between HTTP requests. This could range from keeping track of items in a shopping cart to monitoring user behavior.
Fundamentally, cookies are HTTP headers. When a server sends a response that contains a set-cookie
header, browsers are designed to store this information. Consequently, for all future requests to the same domain, the browser will automatically include this stored information in the form of a cookie
header.
For instance, consider a server response:
If the user visits another page (sending a request), the browser automatically adds a cookie
header:
This allows the server to save info from one request and retrieve it on later requests from the same browser.
Cookies come equipped with attributes that dictate their behaviour:
Expiry: By default, a cookie is termed a "session" cookie and lasts until the user closes the browser. However, its lifespan can be extended using the Max-Age
attribute. For example, set-cookie: test=123; Max-Age=60
ensures the cookie persists for 60 seconds.
Security: Given that cookies can carry sensitive information, especially related to authentication, their protection is paramount.
The **HttpOnly**
attribute prevents JavaScript from accessing the value. This is important to avoid malicious scripts stealing cookie data (XSS attacks):
The **Same-Site**
option prevents cookies from being sent on requests from other domains. This is important to avoid other sites impersonating your users (CSRF attacks):
The **Secure**
option stops the cookie being set on un-encrypted connections. This is important to stop hackers intercepting requests and stealing cookies (MITM attacks):
So how do we actually track whether a user is logged in?
The simplest way is to put all the info you need into cookies:
The server can read this JSON string and parse it into an object to find out info about which user is logged in.
This is called "stateless" as no state is stored on the server. Assuming the server can trust the cookie it can trust this user previously logged in.
But can you trust cookies? Cookies are just HTTP headers, so they're easy to fake:
You can even edit them using dev tools
We can use cryptography to create a value that we can verify later.
Cryptography is the practice and study of techniques for secure communication.
A "hash function" takes a value and a secret, and returns a "hash":
Hashing is a one-way process. There's no way to get the value back.
Hashing the same value with the same secret will always produce the same result:
The only way to recreate this value is to know the secret.
We can use this to "sign" our cookies:
When the server receives the cookie it can re-hash the value ("hello") using the secret only it knows. If the hash matches the one in the cookie the server knows it hasn't been tampered with.
You won't have to implement this yourself. It's safer to rely on battle-tested libraries for security features.
Cookies have a 4kb size limit. You'll often want to store more user info than that.
The server cannot control who is logged in. If a user presents a non-expired cookie they are authenticated.
This is the opposite of stateless auth. Store a single "session ID" in the cookie:
The server reads the cookie, then uses it to look up the saved session data. This would usually be stored in a database.
Since the session ID is basically a password it must be secure.
Session IDs should be long random strings. This prevents people from guessing them.
They should also still be signed with a hash, so you can trust them.
It's important to treat security very seriously. The web has been plagued by serious breaches.
As web developers you have a responsibility to safeguard your users' private data.
The average user re-uses the same password for most sites. If you half-ass your site's security and get hacked that has wider repercussions.
Don't roll your own crypto.
The golden rule of security. If in doubt, look it up. Find out what is popular and recommended by experts.
Building a good secure user-experience takes time and effort. Here are some features we haven't covered:
Email verification
Password resets
Preventing automated mass account creation
Banning abusive accounts
If you don't have the time or ability to do it properly (e.g. you're hired for a 2 week freelance project) use a trusted 3rd party service.
In modern DevOps, cloud infrastructures, especially platforms like AWS, GCP, and Azure, play an integral role. These platforms offer robust APIs that enable developers to provision and manage resources dynamically, streamlining operations and costs.
Why use Cloud APIs?
Automation: Scripted provisioning removes manual errors.
Scalability: Dynamically adapt to demand.
Flexibility: Customise per requirements.
Integration: Blend with CI/CD pipelines and other DevOps tools.
Before making any requests to a cloud provider’s API, you need to ensure you have the correct permissions and authentication setup.
Obtaining API Keys or Authentication Tokens:
Cloud providers typically use a combination of access keys, secret keys, or tokens for API authentication.
Storing Credentials Securely:
Hardcoding or manually handling credentials can lead to security breaches.
Here, you communicate with the cloud service, requesting various operations.
Provisioning: This refers to the allocation or reservation of cloud resources. E.g., Creating an EC2 instance or reserving a new RDS (Relational Database Service) instance in AWS.
Configuration: After provisioning, resources might need additional settings or adjustments. E.g., Adjusting the security group of an EC2 instance or updating the database version in RDS.
Monitoring: Cloud services often provide metrics, logs, or alerts to monitor the health and performance of your resources.
De-provisioning: When a resource is no longer required, it should be terminated or stopped to prevent incurring unnecessary charges.
E.g., Terminating an unused EC2 instance or deleting an obsolete S3 bucket.
Every API call receives a response. Handling these responses correctly is crucial.
Success Responses: Usually, a 2XX HTTP status code (like 200 OK). The response body might contain the details of the newly created resource, confirmation of the action taken, or data you requested.
Error Responses: Cloud APIs can respond with errors for various reasons – rate limits, failed authentication, unavailable resources, etc. For instance, AWS provides detailed error messages within an XML tag in the response. Knowing how to parse and react to these messages is essential. Handling AWS Error Messages
These resources are helpful extra reading that may clarify or enhance concepts you're learning in the main curriculum.
Official counterpart to the Node docs. Useful for getting realistic examples of features when the docs are overwhelming and confusing.
Popular (if slightly outdated) overview of what Node is and how it works.
General background info on how servers work
Intro to servers, their relationship with web browsers, and the role they play in the wider context of web development.
At the heart of the internet, we find two key players: servers and browsers.
Any computer can act as a server. There's nothing inherently special about a server. In fact, your personal laptop could function as one. However, in practice, servers tend to be more powerful machines due to the demanding tasks they often perform. They are computers configured to run software that understands HTTP requests and provides data and services to other computers, known as clients, over a network.
The server is the second half of the HTTP model. The client sends requests for resources, and the server receives these requests and sends responses. Here's a simple example:
Client Request:
Server Response:
In this example, the client is requesting a search for "cats," and the server responds with an HTML document containing an image of a cat.
A web browser is a software application that executes untrusted code sent over the internet. To ensure security, browsers have strict limits on what they can do. This limitation is often referred to as the "sandbox." For example, they can't read files on your Desktop. As a web developer, you have no control over the browser environment - users can run any browser software, apply custom CSS, use extensions, or block specific parts of the page.
JavaScript, often abbreviated as JS, is a dynamic programming language that has significantly evolved since its inception and has become a cornerstone of modern web development.
JS started life as a basic scripting language for web pages. It was mostly used for simple tasks like showing and hiding elements, changing colours, and other rudimentary interactivity. Despite its initial simplicity, almost every web developer had to learn JavaScript as it was the only dynamic language usable in the browser. This necessity led to a significant population of JavaScript developers.
As the number of JavaScript developers grew, so did their ambitions. They wanted to do more than just program web browsers. They desired to leverage their JavaScript knowledge to build more complex applications, but they were limited by the constraints of running JavaScript solely in the browser.
A significant turning point came in 2009 when Ryan Dahl created Node.js. He extracted the JavaScript engine out of Chrome, creating a runtime that allowed developers to run JavaScript separately from the browser. This innovation meant that JavaScript could now be used for anything - web servers, Command Line Interface (CLI) programs, native apps, and even operating systems.
The key difference between browsers and servers lies in the control and execution of code. In a browser, your code is running on their computer (i.e. the user’s computer). In contrast, on a server, your code is running on your computer.
Servers have no DOM: The Document Object Model (DOM) doesn't exist until a browser receives an HTML response and constructs it. This means window
and document
objects are undefined on the server.
Servers are Secret: In the browser, all code is sent to the user, and they can view it all in the developer tools. Users cannot see the code running on your server (assuming it is secured correctly). They will only see what you send in the HTTP response. This means it's safe to use API keys and other secrets on your server.
Servers are Shared: In the browser, your code runs separately on each user's computer, meaning one user can't see another user's data. You usually have one server for all users, which means you can share variables between requests. However, be careful, as you could accidentally show one user's data to another.
Node.js is a runtime environment that allows JavaScript to run on the server-side. It comprises roughly two parts:
The JavaScript language, including syntax and general-purpose features like arithmetic, variables, functions, loops, and promises.
Ways to access the underlying computer that browsers don't have.
While browsers implement Web APIs to provide useful features like document.querySelector
, window.location
, and element.clientWidth
, Node doesn't implement these since they mostly don't make sense on a server. Instead, Node provides additional APIs for tasks like creating an HTTP server and accessing the computer's filesystem.
This document provides an in-depth exploration of single-page applications (SPAs) and their role in modern web development. A particular focus is placed on the React framework, which has significantly influenced the way SPAs are developed.
The history of web development is marked by a shift from server-side rendering to client-side rendering, where much of the application logic now runs in the browser, leading to the development of SPAs.
Historically, web development relied heavily on server-side rendering. In this model, when the browser requested a page, the server processed that request and responded with HTML for the browser to render. The browser acted as a "thin client," meaning it simply displayed what the server gave it and handled minimal logic.
Client-side JavaScript was used to add a layer of interactivity (like modals) to the page, but the majority of the heavy lifting was done on the server side, with HTML serving as the source of truth*.*
Advantages of SSR:
Simplicity: Browsers automatically handle a plethora of tasks, reducing the need for developers to implement complex features via JS.
Imagine implementing links using JS. It’s easy to miss but native elements like <a>
and <form>
handle a lot of complexity.
Language Flexibility: Server-side code can be written in any language, including PHP, Ruby, Python, Java, etc., providing a broad selection for developers.
Hardware Power: Web servers typically run on powerful dedicated hardware, while client-side code runs on the user's device, which can often be an underpowered mobile phone.
Security: Server code is hidden from the user, preventing access to sensitive data and secrets, and ensuring a higher level of security compared to client-side code.
Disadvantages of SSR:
Perceived Performance: Every interaction with the site requires a request to the server and back. Full page loads can make the site feel slower to users.
Limited Interactivity: Building dynamic, interactive applications that can compete with native applications is more challenging.
Server Maintenance: Deploying, securing, and maintaining a server can be expensive and complex, especially for popular sites.
Separate Developer Skill Sets: Historically, backend and frontend development were separate skill sets, often requiring two teams to write in two different languages, which can be inefficient and costly.
With SPAs, all application logic runs in the browser, and only one HTML page (index.html
) is requested. Following this, all routing and templating occurs in the browser via JavaScript.
While database access is still server-side (for security reasons), all application logic and templating occur in the browser. The application fetches JSON data from servers (either third-party or owned) and uses this data to render dynamic Document Object Model (DOM) content. In this model, JSON becomes the source of truth.
Advantages of SPAs:
Perceived Performance: SPAs don't require full page reloads for small changes, and fetching JSON to update a section can feel faster to users.
Interactivity: More dynamic interactions are possible with SPAs. Features such as list filtering, element deletion, and animated transitions become easier to implement.
Reduced Server Needs: If an SPA uses third-party APIs, it doesn't need a server of its own. Free static hosts like Netlify can host the HTML, CSS, and JavaScript files, bypassing the complexities and expenses of server management.
Full Stack JavaScript: The same developers can write both the frontend and backend code in JavaScript, increasing efficiency.
Disadvantages of SPAs:
Complexity: Building non-trivial applications in client-side JavaScript can be challenging, particularly when managing the ongoing state of the application.
Mandatory JavaScript: SPAs can only run JavaScript in the browser, which isn't necessarily the best language for certain tasks (e.g., precision currency calculations).
Hardware Limitations: SPAs run on the user's device (often a £100 Android phone with a CPU from 5 years ago), which may not have the processing power of a dedicated web server. JavaScript can be slow to parse and execute on older devices.
Security: All code executes in the browser, which can't hide API keys or validate user input, necessitating a server to ensure security.
Rendering Delay: SPAs initially display a blank page until the JavaScript loads, parses, and executes. JavaScript is the "slowest resource per byte," meaning it takes longer to run 1KB of JavaScript than render 1KB of HTML.
Large Downloads: SPAs require users to download all the application's code, offloading processing from the company servers to the user's device.
Frameworks such as React help manage the complexity of building big applications by providing a shared structure for developers and handling lower-level DOM updates.
Advantages of Frontend Frameworks:
Shared Understanding: A framework provides patterns for structuring code within a team and often has extensive documentation available online.
User Experience: Good frameworks facilitate building cool stuff and can empower newer developers.
Developer Experience: Frameworks can make building complex apps more enjoyable and often come with built-in features that developers want.
Disadvantages of Frontend Frameworks:
Performance: Frameworks are additional code that must load before your own. They can also encourage bad habits leading to bloated apps, e.g. just ****npm install do-the-thing
.
Lock-in: React apps, for instance, can't usually use libraries written for Angular. An organization tends to commit to one technology.
Limited Control: Frameworks like React are built for specific uses (in React's case, Facebook). They might add features you don't need or refuse to add features you want.
React, a JavaScript library for building user interfaces, primarily for SPAs, offers numerous benefits for developers.
Declarative UI: Instead of instructing the browser on each step to render an element, developers can describe it using JSX (JavaScript XML), just like HTML. This approach includes event listeners, making interactions more declarative.
JSX Closeness to HTML: JSX, an HTML-like syntax used with React, allows developers to write HTML structures inside JavaScript.
Component Model: React encourages dividing your app into pieces or "components," each with its markup, styling, and behaviour, providing a logical mental model and encouraging code reuse.
"Just JavaScript": React doesn't require a special templating language. Developers use JavaScript conditionals, variables, and loops to render markup.
"UI as a Function of State": React follows the principle of "UI as a function of state," meaning for any given state, the rendered DOM should always be the same. Developers only need to update the state, and React ensures the UI stays in sync. This approach simplifies the management of the UI based on state changes and allows React to manage the underlying DOM updates.
By focusing on "UI as a function of state," React upholds the idea of "pure functions," where the output is always the same for the given input, and no other part of the system is affected. Thus, the UI is directly derived from the state of the application, simplifying the correlation between the state and what the user sees.
By embracing these features, React provides a compelling case for developers seeking to build robust, interactive web applications that need to manage complex state changes and ensure a high degree of interactivity. React helps abstract away many complexities, allowing developers to focus on building the best possible user interfaces.
A programming paradigm is a way of thinking and structuring code that provides guidelines and patterns for solving problems. It encompasses a set of principles and techniques that determine how software is designed, organized, and executed.
Imperative
Procedural
Object-Oriented
Declarative
Functional
Logical
Reactive
Event-driven
Concurrent
Parallel
Domain-Specific
This is not an exhaustive list of all the paradigms that exist, however they are some of the more popular ones.
We will be focusing on the following 3:
Imperative
Declarative
Reactive
Imperative programming is a programming paradigm where programs consist of a sequence of instructions that explicitly state how to achieve a desired outcome. It focuses on changing the program's state through direct manipulation of variables and control flow structures.
Let's say you have a recipe for making a sandwich. In an imperative programming paradigm, you would follow a sequence of steps explicitly stated in the recipe to achieve the desired outcome of making the sandwich.
Gathering the necessary ingredients (bread, lettuce, tomatoes and mayonnaise)
Spread mayonnaise on the bread
Add the lettuce and tomatoes
Assemble the sandwich.
In this example, the recipe serves as the sequence of instructions, and you are following those instructions step by step to achieve the specific outcome of making the sandwich. Each action changes the state of the sandwich (adding ingredients, spreading condiments) until the desired state (a complete sandwich) is reached. This illustrates the imperative programming paradigm's characteristic of explicitly stating and executing a sequence of instructions to accomplish a specific task.
Let's look at a simple coding example that calculates the factorial of a number
In this example, the factorial() function calculates the factorial of a given number using an iterative approach. It initializes a result variable to 1 and then uses a for loop to multiply result by each number from 1 to n.
The code follows a sequence of steps explicitly defined in the function, executing each instruction in order to achieve the desired outcome of calculating the factorial. It represents the imperative programming paradigm by explicitly stating how to accomplish the task and manipulating the program state (the result variable) to achieve the desired result.
Declarative programming is a programming paradigm where programs specify the desired outcome or goal without explicitly stating the control flow or steps to achieve it. It focuses on describing what should be done rather than how to do it.
Consider a shopping list. Instead of specifying the exact steps to go to the store, navigate through aisles, pick up items, and pay at the counter, a declarative approach would be to simply list the items needed and let someone else handle the implementation details.
Milk
Eggs
Bread
Orange Juice
Let's look at a simple coding example that filters even numbers from an array
In this example, the filter() method is used to declaratively specify the desired outcome of extracting even numbers from the numbers array. By providing a callback function that checks if a number is even (num % 2 === 0), the filter() method takes care of iterating over the array, executing the logic, and returning a new array with the filtered results.
The code expresses the desired outcome (filtering even numbers) without explicitly stating how to perform the iteration or filtering. The declarative programming paradigm allows us to focus on the "what" (filtering) rather than the "how" (iteration and condition), letting the underlying implementation handle the details.
** Imperative **
Here you're giving the function specific instructions to create a div with the class "box" and contain a "Hello World" message.
** Declarative **
Whereas, with declarative programming you define the div element's className as "box" yourself, without giving instructions on how that div should be created.
Pros:
Simplicity: Declarative programming simplifies code by focusing on the desired outcome rather than the detailed steps, making it easier to read, understand, and reason about.
Abstraction: Declarative code promotes abstraction and encapsulation, allowing for reusable and modular components that can be composed to solve complex problems.
Cons:
Learning Curve: Declarative programming may require a shift in thinking and understanding higher-level abstractions, which can initially be challenging for developers more familiar with imperative paradigms.
Limited Control: Declarative code abstracts away control flow and implementation details, which can be limiting in certain scenarios where fine-grained control or performance optimizations are required.
Pros:
Control: Imperative programming provides fine-grained control over the execution flow, allowing developers to explicitly define the sequence of steps to achieve a desired outcome.
Flexibility: Imperative code can be more flexible and adaptable, as it allows for direct manipulation of program state and detailed control over low-level operations.
Cons:
Complexity: Imperative code can become complex and harder to reason about as programs grow in size and complexity. The explicit control flow and mutable state can lead to code that is harder to understand and maintain.
Code Reusability: Imperative code often tightly couples the logic with the specific implementation, making it less reusable in different contexts or for different tasks.
Reactive programming is a way of writing code that focuses on how data changes and flows over time. It allows developers to easily define and handle data streams in a way that is responsive and event-driven.
Here are two example of some code that take a name as a parameter and will output a h1 message "Hello, {name}".
In the above example, we utilize JSX syntax, which is commonly associated with React. JSX allows us to write HTML-like code within JavaScript, making it easier to define and render components. The Greeting component is defined as a function that receives a name prop and returns an HTML element. The App component renders the Greeting component with the name prop set to "John".
The above code example is written using vanilla JavaScript but achieves the same result as the JSX example. The Greeting component is defined as a function that creates a new HTML element, sets its text content, and returns it. The App component creates an instance of the Greeting component, appends the returned HTML element to the document body.
Comparatively, the JSX approach provides a more intuitive and concise syntax, resembling HTML, and simplifies the process of creating components.
In vanilla JavaScript, the equivalent code requires manual element creation, manipulation, and appending to the DOM.
JSX, with the help of a tool like Babel, transpiles the code into plain JavaScript, but it enhances the readability and maintainability of the code for developers working with React or JSX-based frameworks.
Amazon CloudWatch is a monitoring tool used to collect and visualise real-time logs, metrics, and event data in automated dashboards.
A quick overview of different programming paradigms with code examples.
An overview of programming paradigms with coding examples in different languages such Visual Basic, C and Fortran.
A fun little video explaining some of the programming paradigms not covered in this section.
For AWS: You'll set up IAM (Identity and Access Management) users and grant them permissions. Once set up, you'll be provided with an Access Key ID and Secret Access Key.
is a service that helps you protect access to your applications, services, and IT resources without the upfront infrastructure management. Secrets can be database credentials, passwords, third-party API keys, etc. AWS Secrets Manager Documentation.
E.g., Using Amazon CloudWatch to get logs from a Lambda function or metrics from an EC2 instance.
This week is the first build sprint of your in-house project build.
Work through your sprint backlog, assigning user stories to members of the team.
There are no defined spikes for this week.
You may find that you need to manage spikes within your sprints. Remember to follow the techniques you followed earlier in the programme.
You're encouraged to continue role circles with those who are playing the same role as you.
This week, spikes will be in your project groups.
Use this as an opportunity to read and explore documentation on a new technology that you might need for your project, or to find a definitive answer for some of the "How might we" questions that came up during the definition workshop.
If you are looking into new tech, here's a checklist to keep in mind during your research.
List out your needs, and compare them to a list of the pros and cons of the technology you're looking at.
How popular is it? How well maintained is it?
How good is the documentation? What is the learning curve compared to things you have already used?
Are there good external learning resources? (look into different media types - eg: video)
How much time would go into learning vs implementing?
Does it require payment/ does it have limits on usage that would hinder your project?
Your project in Design Week is to create a wireframe in Figma and test it with your user group.
Take ideas from your Definition workshop and the sketches you did there. You can consider the ideas you came up with there as low-fidelity prototypes and with Figma, you'll create a high-fidelity prototype.
Your wireframe should include the main steps of the user journey. Think about which parts of the journey you'd like to get feedback on from your users and prioritise building these.
This is a guide to what you should be doing for homework each week. Please reach out to your CFs if you are unsure of what to prioritise between sessions.
During this module you should be working on: Execute Program Regular Expressions
We expect you to complete Modern Javascript Level 2 by the end of Week 12
Introduce learners to the concept of an ‘elevator pitch’
Introduce best practice to learners when pitching themselves
Introduce learners to common interview questions
Introduce best practice when answering common interview questions
User Research & Usability Testing
You should be focusing on meeting these learning outcomes over the three-week period. You will be tested on your learning during weekly quizzes.
Your project is to build a dynamic web application that queries at least two APIs and presents useful and/or interesting information to the user. You will be using Node.js and Express, which will involve serving a static web page, creating JSON endpoints, and generating dynamic content through both server-side and client-side code.
Server-Side Setup:
Initialise a Node.js project using Express.
Serve a static web page that will be the front end of your application.
Static Web Page:
Create an index.html
file within a public directory.
This page should include placeholders where dynamic content will be displayed.
Creating JSON Endpoints:
Implement routes in your Express server that respond to GET requests.
These routes will fetch data from external APIs and return it in JSON format.
Dynamic Content:
Write client-side JavaScript that makes requests to your server-side endpoints.
Dynamically update the static web page with the data received from these requests.
Client-Server Interaction:
Ensure that the server acts as an intermediary for API requests, handling data fetching and processing.
The client-side script should handle the presentation of data, updating the user interface based on server responses.
Implement error handling in both server-side and client-side code to manage failed API requests or unavailable data.
Implement tests
Enhance the user interface with CSS and interactive elements for a better user experience.
Introduce additional client-side interactivity, such as user inputs to filter or customise the data displayed.
Ensure your application's design is responsive and accessible.
Document the user journey and your application's functionality in a README file.
Securely store any API keys or sensitive information required by your server.
Host your code in a Git repository with clear documentation.
Deploy your application to a cloud platform, ensuring it's publicly accessible.
Set up the basic structure of your web application and make a call to a single API.
After establishing the basic web app framework, you'll enhance the application by integrating more complex functionalities, including multiple API calls and/or incorporating OpenAI's API.
Open AI API - https://platform.openai.com/
JokeAPI - https://jokeapi.dev/
The Dog API - https://thedogapi.com/
The Cat API - https://thecatapi.com/
Unsplash it - https://unsplash.it/
Corporate Buzzword API - https://corporatebs-generator.sameerkumar.website/
REST Countries API - https://restcountries.com/
UK Police API - https://data.police.uk/docs/
Postcode Lookup - https://postcodes.io/
Twitter API - https://developer.twitter.com/en/docs/twitter-api
Google Maps API - https://developers.google.com/maps
Spotify API - https://developer.spotify.com/documentation/web-api/
Giphy API - https://developers.giphy.com/docs/api/
GitHub API - https://docs.github.com/en/rest
The Movie DB API - https://developers.themoviedb.org/3/getting-started/introduction
The Guardian API - https://open-platform.theguardian.com/documentation/
News API - https://newsapi.org/docs/endpoints
TfL API - https://api.tfl.gov.uk/
Random UK Postcode Explorer: Develop an application that jumps to a random UK postcode and collates various information about that location. Use the Postcodes.io API to generate a random postcode and then fetch data such as weather from the OpenWeatherMap API, local crime statistics from the UK Police API, and perhaps even demographic information if available. This app could serve as an interesting way to explore different parts of the UK, offering insights into the climate, safety, and other aspects of various locales.
Entertainment and Social Media Buzz Tracker: Use The Movie DB API and Twitter API to track social media buzz around movies. Develop a platform where users can see real-time tweets about movies, gauge popularity, and view movie details like ratings, casts, and synopses. This could serve as a guide for movie enthusiasts to discover trending movies.
AI-Assisted Weather and News App: Combine OpenWeatherMap API and NewsAPI. Optionally integrate OpenAI's API to summarize news articles or generate insights based on the current weather data, like suggesting indoor activities on rainy days or outdoor events when it's sunny.
AI-Powered Social Media and Movie Insights: Use the Twitter API and The Movie DB. Optionally enhance with OpenAI's API to analyze tweets for sentiment about movies, offering insights into which movies are most loved or creating thematic summaries of social media discussions.
Intelligent Mapping and Transport Planner: Merge Google Maps API with TfL API and optionally enhance with OpenAI's capabilities. The AI could predict traffic patterns, suggest optimal routes, or offer travel recommendations based on historical and real-time data.
AI-Enhanced Recipe and Shopping Assistant: Combine Recipe Puppy with a supermarket API. Optionally use OpenAI's API to suggest recipes based on user preferences or trends and generate optimized shopping lists considering dietary needs and ingredient availability.
Community Safety App with AI Analysis: Mashup the UK Police API with Postcodes.io, and optionally enhance with OpenAI's API for crime data analysis. The AI could identify safety trends, provide tailored alerts, or offer insights into community safety based on crime statistics and location data.
How would you effectively find out where (and why) an error is occurring in your JavaScript code?
What console
methods are there other than console.log
? Can these help us debug?
What does the debugger;
statement do?
How do we use the debugger in our browser?
How can we send and receive test network requests while working on an application?
How can we inspect any requests the browser is making on an HTML page?
How can we manually send test requests outside of our browser?
How can we find out why our page doesn't look right?
How can we see and edit what elements and styles are rendered to the page?
How can we easily test how responsive our page is?
How can we debug CSS grid and flexbox layouts?
Reinforce your learning by building something fun.
Q&A
Express workshop review
Server-side API mash-up project
Live code session: Dev tooling
Writing cover letters and job applications
Project planning and development
Saturday 16th March
Q&A
Non technical mock interview preparation
Project updates
Live code session:
Project planning and development
Q&A
Project group code reviews
Project presentations
Introduce the software developer labour market landscape
Introduce the Employer Engagement function
Introduce employability curriculum
Explore multi-modal strategies for finding employment
This is a guide to what you should be doing for homework each week. Please reach out to your CFs if you are unsure of what to prioritise between sessions.
During this module you should be working on: Execute Program Modern Javascript Level 1
We expect you to complete Modern Javascript Level 1 by the end of Week 3
Complete the Git, CSS, Semantic HTML, Accessibility and HTML forms workshops ahead of Week 1
Complete github profiles
Project work
Complete projects ahead of Week 3 code reviews
Complete the Asynchronous JS, Promises & fetch, Real-world fetch and Promise practice workshops ahead of Week 4
Your challenge is to build an agency website for your team.
Your website should give potential clients:
An introduction to your agency
Information about each member of your team
A way to get in touch if they are interested in working with you
A user story is a description of one or more features of a piece of software.
As a potential client, I want to:
See information about each member of your team so that I can know who you are
Browse your website on mobile, tablet, and desktop devices
Click to navigate to different sections of your webpage
Contact you to enquire about working with you
Visit your website at a publicly accessible domain name
Additionally, as a visually impaired user, I want to:
Navigate your website using keyboard controls
Hear my screen reader describe the content on your website
User stories come with acceptance criteria - a detailed scope of a user’s requirements.
Navigation menu
‘About us’ section
Contact form
A user cannot submit a form without filling out all of the mandatory fields (name, company name, email address)
Information from the form doesn’t get submitted until the user clicks a button
Use the automatic trigger functionality of your GitHub project board.
Finally, feel free to get creative with the content of your website! Good luck!
This topic is focused on the fundamental building blocks of web pages—accessible, semantic HTML, and well-organised CSS.
To be completed ahead of Week 1
Dev machine setup
Intro to Git and GitHub
Safeguarding and Prevent
Workshops: Git, CSS, Semantic HTML, Accessibility, HTML forms
Knowledge Quiz
Q&A
Feedback session
Employability introduction
Review workshops
Introduction to GitHub profiles
Project introduction
Knowledge Quiz
Q&A
GitHub profile crit
HackMD
Project planning and development
Project updates
Introduction to mock interviews
Knowledge Quiz
Project planning and development
Live code session: project code review
Project code reviews
Project presentations
Knowledge Quiz
Saturday 27th January
How do you write markup so that your page is accessible to as many users as possible?
Who does semantic HTML benefit?
How does ARIA relate to HTML?
What's the difference between accessible and inclusive?
How should you write CSS to ensure it's easy to read, maintain and scale as a website grows?
Why are CSS naming conventions useful?
When might specificity become a problem?
How can composition help us build UIs?
How does CSS decide where to put elements on the page?
What is the box model?
How does the display
property affect layout?
How does the position
property affect layout?
How do you design and build a webpage that looks good on any device?
What CSS units should we use for dimensions? What are absolute and relative units?
When should you use a media query? Are they only for screen size?
How can mobile-first CSS make responsive styling easier?
How can we leverage Github projects to help us plan and track work?
These resources are helpful extra reading that may clarify or enhance concepts you're learning in the main curriculum.
An explanation of how flex-grow
, flex-shrink
and flex-basis
work for elements inside a flexbox container.