This document will guide you through contributing changes to the new UBC Launch Pad website! It assumes basic knowledge of git and pull request workflows. If you are looking for what you can contribute, see:
If you spot anything out of date or incorrect, please open an issue!
Table of Contents
The most important dependencies of this project are:
- Node, which powers all of our Javascript development locally
- TypeScript, a typed superset of JavaScript
- Vue.js, a framework for building web interfaces
- Bulma, a pure-CSS layout/component framework
- animate.css, a pure-CSS animation framework
- Sass (
.scss
syntax), a stylesheet language we use for styling
To get started, make sure you have Node installed:
node -v
npm install
Refer to the links above for more details on each dependency.
Once you are set up, you can run the website locally by running the following and visiting localhost:8081
- see Scripts for more details:
npm run serve
npm is a package registry for JavaScript/Typescript/etc libraries. Our npm dependencies are declared in package.json
.
When declaring dependencies in package.json
, always use the ~
operator, which specifies that the npm install
should only use the latest patch updates of dependencies, and not automatically upgrade to the latest minor updates without explicitly being told to do so.
Visual Studio Code with extensions like Vetur and ESLint is recommended.
This codebase is largely contained in src
, where you will find the following directories, with particularly important ones highlighted:
- ⭐
src/assets
: assets (images, etc.) that get bundled in the application - see Assets and Images for more details src/components
: Vue components that are shared throughout the website- ⭐
src/sections
: the website is mostly designed around horizontal sections that you scroll through - each section you see is defined as a Vue component here. Any content that cannot be configured withconfig.ts
will likely be hardcoded in one of these sections. src/lib
: library of utility functions for Vue componentssrc/mixins
: Vue components can share logic through Mixins - Mixins in use in this project are included heresrc/data
: data type definitions for configuration used in the website - see Configuration for more details- ⭐
src/styles
: global styles are declared here and imported throughout the application
Also noteworthy are the following files:
src/config.ts
: website configuration for frequently updated values - refer to the Configuring the UBC Launch Pad Website documentation site and Configuration for more details. It should only be imported byApp.vue
.src/App.vue
: the main entrypoint component to the site - it declares the site layout and provides data fromsrc/config.ts
to relevant sections components. When you create a new Section, add it here.
Refer to Dependencies for our core dependencies and links to their websites, where you can find documentation on how to use them. Also refer to the existing code and components for guidance on how to work with the codebase.
Some handy scripts/tasks are available in package.json
:
npm run serve
publishes code you write automatically atlocalhost:8081
.npm run build
builds the website and runs other build-related tasks (seepostbuild
), placing the output into/dist
. You can preview the contents of a build withnpm run serve-dist
.npm run lint
reports style and static analysis errors, and can fix some of them for you.npm run vue-ui
starts up the Vue tooling user interface, which you might find helpful! All the above scripts can be run using this UI.
TypeScript is a typed superset of JavaScript, and is used as the main programming language in this project.
Most simple style rules are enforced using eslint
. Our eslint
rules are defined in package.json
. In general:
- always use
<script lang="ts">
in Vue components. - always use
.ts
when adding additional source files. - follow documentation formats used by existing code in the repository.
Vue.js is a framework for building web interfaces, and is the framework that drives this project.
In general, when working with Vue:
- use Vue single file components defined in
.vue
files. - stick to
Vue.extend
(and not class-based components) - see examples
- Add a simple block docstring above
Vue.extend
for all components. For example:/** * About implements a section for introducing visitors to Launch Pad. */ export default Vue.extend({ name: 'About', props: {}, });
- Shared components (
src/components
) should document their props as well with block docstrings:/** * Button is a simple stylized Launch Pad button. */ export default Vue.extend({ name: 'Button', props: { /** * Toggle whether to use a primary, attention-grabbing style or a more lowkey style for this button */ primary: Boolean, }, });
- Stylesheets should use Sass (
.scss
) syntax. - Use existing classes wherever possible - refer to the Bulma and animate.css documentation for what is available. Other global styles are also available in
src/styles
. - Simple, non-specific styles (
margin
,padding
, other modifiers) should be defined insrc/styles
. - Vue declares a
<style />
section at the end of each single file component - use this andscoped
styles for component-specific styles to avoid making unintentional changes to other components, for example:<style scoped lang="scss"> h2 { margin-bottom: 84px; } </style>
See examples.
There are several strategies to handle responsiveness (in other words, how well the website scales onto smaller/larger screens):
- Bulma has a variety of helpers for implementing responsiveness, and each Bulma component likely has a few modifiers to handle scaling on various screen sizes - see their respective class documentation for more details.
- Bulma hide/show helpers (
is-hidden-
classes) are particularly useful for hiding/showing alternative layouts on different screen sizes - see examples
- Bulma hide/show helpers (
variables.scss
has definitions for breakpoints ($tablet
,$touch
, etc.) that you can use with@media
queries in your styles to define screen-size-specific properties - see examples.
Image assets are kept in src/assets
, and are bundled alongside our code during build time. To reference images in Vue:
<img src="@/assets/my-image.png" alt="some alt text">
To load an image to use it as a variable, use require
and bind it to src
(examples)
<template>
<img :src="myImage" alt="some alt text">
</template>
<script lang="ts">
import Vue from 'vue';
const myImage = require('@/assets/my-image.png');
export default Vue.extend({
// ...
data: () => ({ myImage }),
// ...
})
</script>
In general:
- if the image can be hosted elsewhere (i.e. a company website or project repository), host it there instead and reference it by URL
- if you do add an asset to this repository, do not put assets in
/public
, and prefer to import them as demonstrated above from the/assets
folder. - use suitably-sized assets that don't exceed roughly 100kB in size (try an online image compressor, such as compresspng, or whatever is suitable for your format - images can get surprisingly small!)
- lazy-loading:
vue-lazyload
provides some lazy-loading capabilities for images, but be careful where you use this! Especially when animated, lazy-loaded images can look quite bad, since they can just pop up mid-animation (more context here)
We also have an automated workflow that runs on PRs that edit images and automatically adds a commit to compress them if possible while minimizing quality loss - see GitHub Actions.
Try not to use images for icons! We use a third-party icon set - for more details, see unicons.ts
.
We use Fathom Analytics to track visits and interactions on the website. The Fathom client is available within Vue components via this.$fathom
. For the most part, you won't have to manually track page views (see exceptions), but goals are something you'll need to use the client for:
this.$fathom.trackGoal(goalID)
A goalID
is a goal set up in the ubclaunchpad.com Fathom dashboard - reach out to #ask-leads
to add or remove goals. Define and document these goals in lib/fathomGoals.ts
.
See examples.
Site configuration is defined in src/config.ts
, with additional relevant types defined in src/configTypes.ts
. Docstrings and types in these files are used to render the UBC Launch Pad Site Configuration Guide as part of the post-build step to npm run build
or by running:
npm run docs
Included in this documentation website is CONFIGURING.md, where any updated guidance regarding the configuration of the website should be added.
You can view the configuration documentation site locally using npm run serve-dist
npm run build # includes `npm run docs`
npm run serve-dist
The website will be available at http://localhost:5000/config
.
These changes are published automatically when merged into the master
branch - see Deployment.
/tools
contains useful scripts, such as:
generateRedirects.ts
: generates Netlify redirects fromconfig.ts
(see USING.md)stripRequire.sh
: pre-processes compiled JavaScript for execution
Tools are generally used through one of our Scripts.
Deployments are handled automatically by the Netlify - the website is managed under the "Launch Pad OSS Sponsored" team. Build and deploy options can be declared in netlify.toml
.
This means that when your changes are merged to master
, your contribution will automatically be deployed! This deployment includes both the actual website as well as configuration documentation.
Also note that individual pull requests also get their own preview deployment - you can find a link by clicking on "Details" next to the deploy/netlify
check at the bottom of your pull request:
You can use web.dev/measure
to check on the performance of ubclaunchpad.com
. You can also provide the link to a Netlify deploy preview to the tool.
web.dev
points out areas for improvement in web performance, accessibility, best practices, and search engine optimization - you can see a full report for the deployed website here.
GitHub Actions is a workflow automation platform provided by GitHub. We use it for automating a variety of tasks for this project.
- (
checks.yml
) is our continuous integration workflow: it runs on every single pull request to run linters and verify the website builds correctly. Every pull request should pass these checks. - (
compress.yml
) runs on pull requests that modify image assets and, if possible, compresses them without losing too much quality. You should still only add images of suitable size regardless - see Assets and Images.