Blog

Redesigning github and personal website

I had the brilliant idea to look into sprucing up my GitHub profile a bit. There are SOOOOO many ways to do that. You can show everything from cool gifs and animations to cool badges and stats. As part of this "project", I also decided to update the design of my personal website.

First, I started collecting examples (which you can find in a star-list here), and then it was time to do my profile.

I ended up with a simple design with interesting statistics and various information.

As part of this change, I decided to start adding my nickname ("Dragon") to stuff. Since many people only know me by that name, I figured it would make sense. This meant adding it on both GitHub and my personal website.

Regarding the website, I decided the best option would be to somewhat copy the style of my GitHub.

I also remade the start page with some new content and some restructuring.

Storyblok RichText in-line block support for nuxt3 with ssr and prerender.

cetchells on github raised an issue on my github repo for this website to discuss in-line blocks in richtext from contentful. This is not something that I have tried or looked into, but felt like a challenge and something that I will probably want in the future.

Since I use SSR with prerender in nuxt3, there is no built-in way of doing the rendering of blocks inside of richtext, so I had to figure out a custom way of doing it. I settled with looping through the richtext nodes and adding the blocks and HTML to an array. This way I can render the richtext in the correct way and still have support for in-line blocks.

To add a block in richtext you use:
which places a block list inside of the richtext.

After placing a block it looks like this:
which renders like this:

Here is the code for how to do this:

<script setup lang="ts">
import { Richtext } from 'storyblok-js-client';
const props = defineProps({ blok: Object });
const nuxtApp = useNuxtApp();
const textObject = { ...props.blok.text };
const nodes = [];
// Proof of concept for custom handling of inline blok nodes.
Object.entries(textObject.content).forEach(([key, node]) => {
if (node.type === 'blok') {
const blok = {
content: node.attrs?.body?.[0],
};
nodes.push({
key,
type: 'blok',
content: {
blok,
},
});
} else {
nodes.push({
key,
type: 'html',
content: nuxtApp.$formatRichText(useStoryblokApi().richTextResolver.render({
type: 'doc',
content: [
node,
],
} as Richtext)),
});
}
});
</script>
<template>
<div v-editable="blok" class="text">
<div v-for="node in nodes" :key="node.key">
<component
:is="$resolveStoryBlokComponent(node.content.blok)"
v-if="node.type === 'blok'"
:blok="node.content.blok.content"
/>
<div v-else v-html="node.content" />
</div>
</div>
</template>
<style>
.text img {
max-width: 100%;
}
</style>
view raw Text.vue hosted with ❤ by GitHub

Performance Improvements

For some time now i have been working on improving the performance of the site.

I decided to go with https://github.com/danielroe/nuxt-full-static/ which is a suggested implementation of nuxt3 full static. The point of the module is to make it so that all requests for information are prefreched and stored during building/generating.

This proved to be very successful.

I went from a score of ~30 to 97:

Storyblok DateTime Field with today as default

Weirdly enough there isnt a way to have today's date and time as default for a Storyblok DateTime field... So I created one.

const Fieldtype = {
template: `
<div>
<div class="image__wrap uk-margin-small-bottom">
<input type="datetime-local" id="date" name="date" v-model="model.date">
</div>
</div>
`,
mixins: [window.Storyblok.plugin],
methods: {
initWith() {
return {
plugin: 'date-time-today-default',
date: new Date().toISOString(),
}
},
pluginCreated() {
console.log('plugin:created')
}
},
watch: {
'model': {
handler: function (value) {
this.$emit('changed-model', value);
},
deep: true
}
}
}

Sitemap with Nuxt3

Getting a working sitemap for nuxt3 turned out to be close to impossible given that I have a lot of dynamic routes for the portfolio and the blog.

The only solution I found that worked was https://github.com/funken-studio/sitemap-module-nuxt-3. So thanks to Funken-studio for making a working solution.

They even had a working example for Storyblok which was a great bonus.

Github Gist in a Nuxt3 Project with storyblok

So I had the brilliant idea to add support for Github Gists in my portfolio, but to do this I need to add a block in storyblok and also make it work for Nuxt3.

To render the Gist I went with https://github.com/sudhanshu-15/vue-embed-gist to render it, but since I use Nuxt3 I need to do some magic.

To add support to add a gist in my blog system, I added a new block called "Github Gist" that I add through the UI and then add the gist-id and the file name I want to show.

Since there is no Nuxt3 module or similar for a github gist embed, I made my own. Here is the full code:

<script setup lang="ts">
const props = defineProps({
gistId: {
type: String,
required: true,
},
file: {
type: String,
required: false,
default: '',
},
});
const gistUrl: string = 'https://gist.github.com/';
const gistErr: boolean = false;
const { data: result } = await useAsyncData(
`gist-${props.gistId}-${props.file}`,
() => {
const params = props.file.length > 0 ? `?file=${props.file}` : '';
return $fetch(`${gistUrl}${props.gistId}.json${params}`);
},
);
</script>
<template>
<div>
<div v-if="gistErr">
<img
id="notFound"
height="100%"
width="100%"
src="https://user-images.githubusercontent.com/883233/102043641-d4817580-3d89-11eb-885d-2786373932d4.png"
alt="404"
>
</div>
<div v-else v-html="result.div" />
</div>
</template>
<style scoped>
@import url("https://github.githubassets.com/assets/gist-embed-4ac6018bcc05457cde2f66d2e7299d11.css");
@import url("https://fonts.googleapis.com/icon?family=Material+Icons");
</style>

1Password has a shitty autofill

I recently switched from Dashlane to 1password at work, and holy shit the autofill is so much worse on 1password.

On mobile I cant get 1password to autofill at all.
On desktop it just doesn't show up for a number of fields.

For our checkout at work I noticed that the way I could fix this, was to add an id to the field. Autocomplete and type was correct, but apparently they need an id.

This didn't work:

<text-input
  class="editable-address__initial-email"
  type="email"
  autocomplete="email"
/>
<text-input
  id="email"
  class="editable-address__initial-email"
  type="email"
  autocomplete="email"
/>

Very weird. I'm going to contact them to see if I can get them to fix this.

Time for Storyblok - Moving the blog

The next big mission will be to move the blog. This will be a lot more work than moving the portfolio.

To make it more simple for now, I will just have all the entries in a long list and I will skip the categories for now. Pulling the blog entries is fairly straightforward. I am using the API similarly to how I did it with the portfolio, but I am limiting it to only blog entries and I am sorting them right away based on the manual date field that I have included.

The only thing I had to do to make the blog show up correctly is to replace the v-html that I was using previously with the RichTextRenderer that renders the storyblok specific rich text field.

Now comes the tedious part. I am going to write a script to pull all the blog posts from the SQL database and then import it straight into storyblok.

Originally I was going to make the migrator in PHP, but realized that I am faster in Javascript so might aswell do it in pure nodejs.

I made a standalone script that runs nodejs that uses storyblok-markdown-richtext and turndown to convert my HTML richtext into storyblok richtext and then uses the Universal JavaScript SDK for Storyblok's API. You can find the full script here: https://gist.github.com/SebbeJohansson/2f64e0a76e3b786e5ea3ed1cdbf8ca29

The blog post was originally written in my admin panel, but I am now writing inside of storyblok!

Time for Storyblok - Moving the portfolio

The portfolio part is fully working now. So time to move all the entries. I'm gonna do that by hand.

Edit: writing from storyblok I actually decided to import the portfolio too. The only stuff that I didn't bother to migrate was the images, but connecting those was easy.

GA4 roll up property

At work we are preparing for next year when UA (Universal Analytics) stops working in July. To do this we need to add GA4. One of the main things that we need (and that we also are having problems with) is having a roll up (or global) property. In UA we use a custom task to send each event twice, but this is sadly not possible with GA4.

One option is to connect properties using datastreams and "Connected Tags". What we need to do is have a datastream per property and then add the roll up property's GA4 Measurement ID to the list of "Connected Tags" on each of the country properties.

Since we are using GTM to setup our GA4 this is sadly not working. This method ONLY works for GA4 setups that use Gtag.

Time for Storyblok - Connecting it to nuxt

To pull content I will be using @storyblok/nuxt which is an official plugin for nuxt. The setup is easy enough:

  1. yarn add @storyblok/nuxt

  2. Adding it to nuxt.config.ts

    import { defineNuxtConfig } from "nuxt";
    
    export default defineNuxtConfig({
      buildModules: ["@storyblok/nuxt"],
      storyblok: {
        accessToken: ""
      }
    });
  3. Add components that correspond to Stories in storyblok.

  4. For individual stories, I can use const story = await useStoryblok("{{story_slug}}", { version: "draft" }); to pull the data.

  5. For lists of stories (as far as I can tell), I need to use useStoryblokApi() to pull all the stories with "starts_with" as described in the API docs.

For the list of stories, I sadly cant use the built-in features at all. It doesn't allow me to input the slug into the component and other limitations. To combat this, I will use nr 5 to pull the data, but when I have received the stories i will map them as i did with the old cms.

I have now successfully pulled the first information from Storyblok.

Time for Storyblok - Content Setup

For my Storyblok setup, I need a minimum of 2 different content types: Portfolio Entries and Blog Entries.

For the portfolio entry, I need the title, slug, image, description, duration, role, and actual content. Luckily Storyblok has a built-in feature for "stories" where it automatically makes a slug when you input the title. You don't need to create neither the title nor the slug yourself.

For the blog entry, I need the title, slug, created date, and the actual content. Same thing here, title and slug are automatic.

And with that, I have the fields I need. Easy as pie.

Migrating from Nuxt2 to Nuxt3

To be able to use the latest version of Storyblok I need to switch to nuxt3. It should be too much of an issue. Most things should be able to migrate over.

First I created a new project using the guide on their website and then I started following the migration guide.

The steps for me were as follows:

  • Copy over the eslint, git, and nuxt settings.

  • Remove Axios, since I should use fetch instead.

  • Remove GTM and replace it with a script tag in nuxt.config.js.

  • Add gtm and Storyblok using yarn.

  • Migrate components, layouts, pages, plugins, static, store, styles and utils.

  • Switch from to in layouts.

  • _slug.vue => [slug].vue.

  • Change from defineComponent to defineNuxtComponent.

  • Switch from adding composition API to just using ref(), pure functions, computed() etc without adding anything.

  • Rewrite plugins to use useNuxtApp.

  • Switch from <NuxtLink> to <a> for anchor links.

The site is now working with Nuxt3! Now I just need to make the content work, but since I am planning on switching to Storyblok I wont make the old content work.

Moving away from custom CMS/Admin and changing to Storyblok

Lately, I have been working a lot on the CMS for my portfolio and with the performance of the said portfolio. I have realized that a better idea than maintaining an old-school PHP CMS (originally made in high school), is to switch to Storyblok.

They offer a free trial which is pretty much feature complete (as long as you don't need external datasources) and is "forever". Since my portfolio is already built using Nuxt with headless in mind, I should pretty easily be able to switch over to Storyblok.

The journey begins, but not today.

Advanced image handing for my portfolio

To make my site load a bit quicker, I have decided to add more advanced image handling. This will be in two parts: using Imgix to render the images in the best way possible and the other being a media handling plugin that will return an image that is automatically formatted (from imgix based on the users' device) and in an appropriate size. A small addition to this that has already been implemented is "loading=lazy" on all images which will make the images lazy load on supported browsers (everything except for IE11).

Imgix:
I have used Imgix previously so implementing it won't be that much of an issue. I will mainly use the auto=format feature to make the returning image be the best format possible for the user and also setting the height and width to what the actual shown size should be.

Media handler:
This will be a plugin in nuxt that will have a method for inputting an image, a size/ratio, and then returning the most perfect image ever.

Since I am using nuxt-ts and composition API the code for the plugin is as follows:

import { Plugin } from '@nuxt/types'; declare module '@nuxt/types' { interface NuxtAppOptions { $toMediaUrl(slug: string, args: MediaArguments): string } interface Context { $toMediaUrl(slug: string, args: MediaArguments): string } } interface MediaArguments { maxHeight: number; maxWidth: number; skipAutoFormat?: boolean | undefined; } function toMediaUrl(slug: string, { maxHeight, maxWidth, skipAutoFormat = false }: MediaArguments) { const qs = []; if (maxWidth) { qs.push(`maxWidth=${Math.round(maxWidth)}`); } if (maxHeight) { qs.push(`maxHeight=${Math.round(maxHeight)}`); } if (!skipAutoFormat) { qs.push('auto=format'); } let imageUrl = `https://sebbejohansson.imgix.net/${slug}`; if (qs.length) { imageUrl += `?${qs.join('&')}`; } return imageUrl; } const mediaHandler: Plugin = (context, inject) => { context.$toMediaUrl = toMediaUrl; inject('toMediaUrl', toMediaUrl); }; export default mediaHandler;

import { Plugin } from '@nuxt/types';

declare module '@nuxt/types' {
  interface NuxtAppOptions {
    $toMediaUrl(slug: string, args: MediaArguments): string
  }
  interface Context {
    $toMediaUrl(slug: string, args: MediaArguments): string
  }
}

interface MediaArguments {
  maxHeight: number;
  maxWidth: number;
  skipAutoFormat?: boolean | undefined;
}

function toMediaUrl(slug: string, { maxHeight, maxWidth, skipAutoFormat = false }: MediaArguments) {
  const qs = [];

  if (maxWidth) {
    qs.push(`maxWidth=${Math.round(maxWidth)}`);
  }

  if (maxHeight) {
    qs.push(`maxHeight=${Math.round(maxHeight)}`);
  }

  if (!skipAutoFormat) {
    qs.push('auto=format');
  }

  let imageUrl = `https://sebbejohansson.imgix.net/${slug}`;

  if (qs.length) {
    imageUrl += `?${qs.join('&')}`;
  }

  return imageUrl;
}

const mediaHandler: Plugin = (context, inject) => {
  context.$toMediaUrl = toMediaUrl;
  inject('toMediaUrl', toMediaUrl);
};

export default mediaHandler;

Javascript ReplaceAll with regex and return function

Today I had to do some changes to a string that I can not modify on the creation end. To do this I settled on doing a replaceAll with a replace function!

Since I need to make sure that its a complete tag, I had to use namedGroups to be able to put in the new data where I wanted it.

I think this worked fairly well!

(Mainly posting this to have some recording of it, if I ever need it again)

Consent Mode in GTM

At work, I was tasked with creating a new cookie consent popup and a system to connect it to all of our external tags and scripts. Not long ago Google added a new Consent Mode in GTM that is now fairly stable and ready to be used.

To use this new system you need to activate it in your container settings in GTM. After doing this you will have a few new tools to limit what tags fire based on what consent modes the user allows.

There are a few existing templates for Consent Mode, but the majority of them are for specific Cookie providers. The best template for a general implemenation I found was the one Simo Ahava has created, but this is where I encountered some issues. The tags were not firing in the right order.

After a conversation with Google, we have been able to figure out that the issue was that I was using "url_passthrough" on the tags that set the consent. Setting this kind of parameters can cause a delay in the firing process, which it clearly did for us.

After deactivating this setting, the tags are now firing in the right order.

The next step was to set a consent mode for each of the tags based on what consent is needed for that specific tag. For example to set that a tag should only trigger when "ad_storage" access is granted, we do this:

From UA to GA4 with nuxt

Recently we have begun our work to convert our site from Universal Analytics to Google Analytics 4. This project consisted mainly of adding new variables that fit the datamodel that GA4 has and making the Events.

We use GTM so most of the variables are populated from our GTM package in Nuxt. All I had to do was to make javascript variables in GTM that converts the UA values to the GA4 values. One of these is the array of products during checkout which has a completely different structure compared to how it is in the old system.

Reworking my website - Let's deploy.

Deploying the front is done using Netlify. Any code uploaded to GitHub gets automatically deployed and viewable on the Netlify domain.

The process of deploying the admin panel is more manual. Old school uploading files with filezilla.

For the front I want to use my existing domain. To do this I have to map it to Netlify which is easy enough. My site is now live!

Reworking my website - Blog 2.0

So time for the blog to be migrated!

Given how few blogposts I have and how few categories I have, I think I'm going to rework it a little. The plan is to load all blog posts and sort them into different arrays and using filtering I'll show different blogposts using CSS. I think this will work fine for what I need.

For up is pulling the data and just displaying all of them. To do this I just copy the portfolio code and base it on that. Pulling the entries looks something like this:

Now I just need to display them. To be able to filter them I am pulling in the category and adding it as a class on the blogpost. This means that I can make CSS that hides posts that the user does not want to show. Hopefully this works correctly in static mode on Netlify.

The DOM will look like this:

Next is to add the category filtering which will work similarly to how the rest is pulled. Each of the categories has a line which then can be toggled. Toggling a category changes the query of the page and based on the query CSS is generated to hide/show blog posts.

I think the blog will have to be done for now. Running out of time for today.

Reworking my website - Nuxt front

The new website will use a nuxt front that pulls all the data from the new API. I am going to be using Typescript and use a static deployed website using Netlify.

The first step is to create new website and I am using my Nuxt Typescript base, but notably I am removing the translation system (i18n) since I'm not planning on having multiple languages in this version.

Connecting the new website to the API is easy. Im using Axios to make calls to the API and I am doing everything locally which helps with speed.

The first part of the website I'm gonna implement is the actual portfolio entries. I am developing a content system where every content block has the same styling and uses the same component with a <slot>.

As part of this, I am also making a different version that has a title which everything else can use as a base (which is using "ContentBlock" as a component).

The portfolio entries are pretty straightforward. Just add components for the two different types (Big and Small) and add lists that also pull the data. The pulling of data will only happen during the build process in netlify. Since the content wont update automatically, maybe I should implement a rebuild feature into the admin panel when saving data (or a manual button).

To pull the data I do:

which pulls all live portfolios and then splits them into two different arrays.

After the portfolio, it's onto the "contact" portion. Same procedure as with the portfolio.

Now I'm only left with some of the styling stuff and then the blog. The blog will have to happen on a different day.

Reworking my website - API

The plan for the API is to have it on the PHP admin panel side (mainly because that's the easiest and most straight forward for me). The implementation for the API is based on my API for steamdeckdb.net which is heavily influenced by the IGDB api.

To make the API modular so I can use it in other projects, I've decided to add a subdirectory for it ("/api") and implement my prebuilt classes for database connection and API.

The first dilemma that I've thought about is whether I need to require authentication to pull data or not. What is the chance/risk that someone will try and pull a bunch of data with my API endpoints? I reckon it's pretty low. For now, I will not implement an authentication system, but ill have to reevaluate at a later date.

To be able to keep track of the status of an API call I have added my context class with a new "status" class. The context class helps me save and reuse information and the status class will hold the HTTP code and potential error messages.

The current plan for what endpoints I need is:
/portfolio/get
/socials/get
/blog/get
/blogcategories/get

For each endpoint, I will have a way to sort, filter, and limit the result right away. This will be done similarly to how the IGDB works.

Let's start with the portfolio...

Is it possible to make a general structure to the API so that you just input a "table" and an action and it knows where to grab it? Is that the best way of doing it? The API endpoint "dimension" (the first part of the URL) would need to be the same as the table so that I can just reuse it. Preferably I would like to be able to reuse the API without doing any changes. I'm thinking that I can either make one definition for dimensions and one for actions OR I can make just one definition that has a key-value pair between dimensions and actions. I think that the best solution is a key-value pair since I also need to specify accepted columns (since this could be a security issue).

For now, the structure looks like this, which seems to work:

The API is pretty ready. I can pull all the things I need (I think) so I think I'm ready to start making the new site!

Reworking my website - Moving admin

I want to make a new more modern website built with a client-rendered nuxt-ts frontend. Currently, the plan is to add a read-only API for the portfolio admin panel that I can use with the nuxt frontend. The first step to do this is to migrate my current admin panel from the subdirectory on my PHP site (since the domain will point on the nuxt site at a later date).

This turned out to be super easy. I just had to make a new subdomain and then move the site. The only issue I had was to remove all the old hardcoded paths with dynamic paths.

The new site looks exactly the same and has the same features, but with a new url.

Scariest thing I've ever done

During the first game project in college, we had to do a presentation in front of the whole school and it was also live-streamed. For some reason, I volunteered to be one of the people in my group to do the presentation.

We were two people from the group who did the presentation, me (lead programmer) and our lead game writer. Our project leader/lead designer was supposed to join us, but she didn't have time to prepare so we decided to just do it with only us two. I was so nervous and scared of doing it that I almost didn't do it. I have in the past had a really hard time to talk in front of large groups of people, but the more I do it the easier it gets. The presentation went very good (in my opinion at least) and I'm really proud of the work me and the group did for the game. Below is the VOD of the live-stream the school did. We go on at the two hours and ten minutes mark.

It was super scary to do, but I am really glad I did it.

Making games for VR is hard!

Over a year ago I bought my first VR setup. I chose to go with HTC Vive because at the time the Oculus didn't have any controllers released. Right from the start, I was in love, so much so that I could have paid double the price and still been satisfied. VR is amazing.

Now... I knew right away that I wanted to make games for VR because it felt like a fun challenge and a new fun media. My first idea was a snowball war game where you throw snowballs at either an AI or other players. I had already done some development for such a game (but without VR) so I "just" had to convert it to a VR game. This was the game:

As you can see, it's not very good. After some more development and converting it into a VR game, a different developer released a more polished version of the exact same game idea on steam so I gave up on the idea and moved on.

My next game idea was a backyard simulator where I wanted to bring in all the things that you do in the backyard of your house. Initially, the things I wanted to put in was Kubb, throwing knives, bow and arrows, and giant chess. The development went great and I felt like it was a pretty fun idea. But when I started working on networking I got into some problems with the technology and also got very busy in school (and generally in life) so I had to stop working on the game. Below is an example of the throwing knife (more a sword) I was working on.

During my time developing for VR I've realized how freaking hard it is. Trying to develop for VR is so limiting and frustrating sometimes. Not being able to work on the bus or train, having to take on and off the headset, having to move around to try bugs, etc etc etc. Since the technology is so new there aren't a lot of good resources for information on how to develop and design a VR game, so I mostly had to just try it myself and see if it works. Since it's such a different experience compared to developing a normal PC game I often found myself in a weird new situation and encountered weird bugs. One of these bugs was when I was working on making a throwing function and I accidentally made it move the whole player box:

Maybe a way of locomotion for VR games?

Right now I do have time to develop, but I don't have the energy to try and make something for VR. Maybe in the future, I can continue working on my projects and finish it.

Update on Whispers of the Ocean!

7 weeks in and we have gotten a lot further with the game. It is getting close to being finished pretty much. Movement is starting to feel very solid and the world is shaping into place.

Hopefully, we will be finished with the game this week so we can focus on other school stuff.

New game Tap o' War released!

My game Tap o' War is now fully released on Google Play. The game is a very simple game with not very many features. It has two modes, survival (play against an AI) and PvP (local fight player vs player).

I don't think I am going to work anymore on the game. I mostly just wanted to get it released so I don't have a fully developed game just waiting to be released.

Tap o' War development post!

A very long time ago (like half a year) a friend approached me and had some questions about how I would go about making a game idea he had. I suggested making it in Unity and making it in screen-space, but he insisted that it would be better to make it in world-space. Since I would never have gotten the idea to making this kind of a game in world-space I was curious and made a prototype for it. This game has now evolved into a pretty fully made game (a pretty shitty mobile game) and I am right now trying to finish everything up to release it for android.

The game is called Tap o' War and the gameplay is that you tap to increase a colored part of the screen. Right now there are two game modes: PvP and Survival. In PvP you fight against a local opponent (1 half of the screen each) and in Survival the objective is to keep the line from going off screen. Bellow is a quick gameplay example of the survival mode:

Next step is to finish up all the content that is needed to release it.

Game project #2 for college!

A few days ago (almost 2 weeks) we started our 2nd and last game project for the three years of college I am registered to. The school matches us programmers with students from other disciplines of game making. We are around 20 people who are over the next 10 weeks make a game together.

The game that my group is going to be making is called Whispers of the Ocean and it is supposed to be a game about the darker version of the mermaid myth/legend. It is going to be basically a swimming simulator with exploration elements and in the future, if we keep working past the 10 weeks, we plan on adding fighting and stealth to the game.

My part in the project is primarily to make the movement system, but it is very hard to get it how we want it. The biggest goal of the project is to make a movement system that feels very natural and intuitive. So far the hardest part has been to make it feel natural, but I have a feeling that making it intuitive is going to be very hard.

The most recent part I added to the game was the "dash" function (a rapid increase of speed) which didn't go as plan:

As you can see it is far too fast, but it is already fixed to its correct behavior. The next part I will be tackling is to make it fly next to objects very naturally, like in Abzu which has pretty good under water movement.

Improved front- & back-end

Today I put in some actual work to try and improve my blog a bit. Most of the changes was on the back-end, which no one else will ever see (cause the code ugly as fuck and not really secure). I tried to improve the design a bit.

I got some help with the design decisions from a good friend of mine (LostSoul. who apparently wants to be called my 'lifepartner' instead of friend). We came to an agreement that I have too many boxes on my blog front-end. I am trying to go for a material design and boxes with shadows are pretty common (and I love them), but I decided to remove some of them and added a line under every single post instead.

Next up: Categories needs to be fixed and implemented.

New longboard :D

Hi! It was long overdue to get a new longboard so I finally bought one. Last time I bought a longboard it was an Warp generic thing I got for $50, so this time I wanted to do it right.

I got help from the longboarding subreddit (/r/longboarding) to pick out a setup that would be perfect for me. I decided on a commuter/freeriding setup with the potential to be used for more serious downhill riding.

Setup:

  • Rayne Nemesis V3 - Shipwreck Graphic

  • Gullwing Reverse 10 inch Truck (white)

  • Madrid Flypaper Griptape 12 inch

  • Moonshine universal skate tool (apparently I'm going to find this very helpfull)

  • Powell Paralta Snakes 69mm wheels (red)

  • Venom Downhill Bushings (green)

  • Venom Downhill Bushings (red)

  • Zealous Bearings

Total Cost: 454€ (assembly included)

I truly love the graphic on the deck. At first I was going to go for a deck without graphic (pure wood), but I fell in love with the Rayne Shipwreck graphic so I decided to go with a board that has that graphic. At first I was going to go for the larger version (Demonseed), but after seeing a video of it I realized that it was far too big for me.

The rest of the setup I pretty much trusted the community to pick good things for me.

This is how the setup looks:

Bucket list

Hi.

I've realized that I want to make a bucket list. I've never really done one before. The start of the list is going to be the 100 things I wrote down for the excercies I talked about in my last post.

Im still not sure if im going to post the whole list on here. For now its not going to be posted.

Life goals

Hi.

Welcome. This is my first real blog post I would say. I recently realized that I dont know what the fuck I want to do with my life, so my ex suggested a exercise where you say 100 things you want to achieve or do and sort it into 3 categories (A, B, and C). From the things added to category A you pick the 10 most important of those things and write a short text about why those things are goals to you.

So far I've made the list of 100 things and categorized it. Next step is to pick the 10 most important things in group A. The final list of the 10 things is:

  1. Graduate from some kind of college.

  2. Become good at italian.

  3. Buy a new longboard. DONE!

  4. Find love.

  5. Become healthy.

  6. Find what I want to do with my life.

  7. Learn to live without a SO (significant other).

  8. Be able to run 10km.

  9. Become good at cooking.

  10. Move to a different country.

These are the 10 things that are most important to me, and the things I should focus most of my energy on. The explanations on why they are on this list wont be post on here.

Edit: 1 down 9 to go.

Second post

This is pretty much just a test to see that the CMS adding of posts works. It does!

I also started to work to add blog categories. Still a lot of work left.

Edit: Just added the ability to edit blog posts. It looks like it works :D

First post

I felt like I needed somewhere to went and write what I am doing. So I decided to make a blog. I will write about anything and all things on here. Both work related things and personal stuff.

Since I wanted to make it from scratch this first blog post is written in directly in the MySQL database using phpMyAdmin.

Next step is to make the CMS part for the blog. It will be using the CMS that I am using for the rest of my portfolio. The CMS probably need to be redeveloped from the ground up some day when I have the time and energy...

Anyway! Welcome to my blog.