diff --git a/components/user/Social.vue b/components/user/Social.vue
deleted file mode 100644
index 60e05e76..00000000
--- a/components/user/Social.vue
+++ /dev/null
@@ -1,18 +0,0 @@
-<template>
-  <div class="social-container">
-    This is a social container
-  </div>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-
-export default Vue.extend({
-  props: {
-    userId: {
-      type: String,
-      default: '',
-    },
-  },
-});
-</script>
diff --git a/components/user/social/Box.vue b/components/user/social/Box.vue
new file mode 100644
index 00000000..4178c533
--- /dev/null
+++ b/components/user/social/Box.vue
@@ -0,0 +1,88 @@
+<template>
+  <Component :is="connectionMeta.link ? 'a' : 'div'" :href="connectionMeta.link" class="social-link-container">
+    <p>{{ connectionMeta.header || connection.platform }}</p>
+    <FontAwesomeIcon :icon="connectionMeta.icon" class="icon fa-6x" />
+    <p>{{ connection.username }}</p>
+  </Component>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import { Connection, ConnectionMeta, ConnectionMetas } from '~/types/api/user';
+
+export default Vue.extend({
+  props: {
+    connection: {
+      type: Object as () => Connection,
+      default: undefined,
+    },
+  },
+
+  computed: {
+    connectionMeta(): Partial<ConnectionMeta> {
+      const connectionMeta = this.connectionMetas[this.connection?.platform] ?? { };
+      if (connectionMeta.linkBase) {
+        connectionMeta.link = connectionMeta.linkBase(this.connection.username);
+      }
+      return connectionMeta;
+    },
+  },
+
+  /* eslint-disable-next-line vue/order-in-components */ // Here, data is way less interesting than computed
+  data() {
+    return {
+      connectionMetas: {
+        DISCORD: {
+          icon: [ 'fab', 'discord' ],
+        },
+        EMAIL: {
+          linkBase: fragment => `mailto:${fragment}`,
+          icon: [ 'fas', 'envelope' ],
+        },
+        FACEBOOK: {
+          linkBase: fragment => `https://www.facebook.com/${fragment}`,
+          icon: [ 'fab', 'facebook-f' ],
+        },
+        INSTAGRAM: {
+          linkBase: fragment => `https://www.instagram.com/${fragment}`,
+          icon: [ 'fab', 'instagram' ],
+        },
+        PHONE: {
+          linkBase: fragment => `tel:${fragment}`,
+          icon: [ 'fas', 'phone' ],
+        },
+        NICO: {
+          linkBase: fragment => `https://com.nicovideo.jp/community/${fragment}`,
+          icon: [ 'fas', 'tv' ],
+        },
+        SNAPCHAT: {
+          linkBase: fragment => `https://www.snapchat.com/add/${fragment}`,
+          icon: [ 'fab', 'snapchat-ghost' ],
+        },
+        SPEEDRUNCOM: {
+          linkBase: fragment => `https://speedrun.com/user/${fragment}`,
+          icon: [ 'fas', 'trophy' ],
+        },
+        TWITCH: {
+          linkBase: fragment => `https://www.twitch.tv/${fragment}`,
+          icon: [ 'fab', 'twitch' ],
+        },
+        TWITTER: {
+          linkBase: fragment => `https://www.twitter.com/${fragment}`,
+          icon: [ 'fab', 'twitter' ],
+        },
+      } as ConnectionMetas,
+    };
+  },
+});
+</script>
+
+<style lang="scss" scoped>
+.social-link-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 4px;
+  padding: var(--spacing);
+}
+</style>
diff --git a/components/user/social/Social.vue b/components/user/social/Social.vue
new file mode 100644
index 00000000..178e1272
--- /dev/null
+++ b/components/user/social/Social.vue
@@ -0,0 +1,48 @@
+<template>
+  <div v-if="user && !user._fetching && user.connections.length" class="social-container">
+    <UserSocialBox v-for="connection of user.connections" :key="connection.id" :connection="connection" />
+  </div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import { mapActions } from 'vuex';
+import { User, UserState } from '~/types/api/user';
+
+export default Vue.extend({
+  props: {
+    userId: {
+      type: String,
+      default: '',
+    },
+  },
+
+  async fetch(): Promise<void> {
+    await Promise.allSettled([
+      this.getUser(this.userId),
+    ]);
+  },
+
+  computed: {
+    user(): User|undefined {
+      return (this.$store.state.api.user as UserState).users[this.userId];
+    },
+  },
+
+  methods: {
+    ...mapActions({
+      getUser: 'api/user/get',
+    }),
+  },
+});
+</script>
+
+<style lang="scss" scoped>
+.social-container {
+  width: 100%;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-evenly;
+  border-block: 1px solid;
+}
+</style>
diff --git a/configs/font-awesome.config.js b/configs/font-awesome.config.js
index dee257ce..4b547113 100644
--- a/configs/font-awesome.config.js
+++ b/configs/font-awesome.config.js
@@ -19,17 +19,24 @@ const solid = [
   'Desktop',
   'Donate',
   'DotCircle',
+  'Envelope',
   'Home',
   'Language',
   'MoneyBill',
   'PaperPlane',
+  'Phone',
   'Plus',
+  'Trophy',
+  'Tv',
 ];
 
 const brands = [
   'Discord',
+  'FacebookF',
   'Github',
+  'Instagram',
   'Patreon',
+  'SnapchatGhost',
   'Twitch',
   'Twitter',
 ];
diff --git a/types/api/user.d.ts b/types/api/user.d.ts
index 9f89cb9d..05d603f5 100644
--- a/types/api/user.d.ts
+++ b/types/api/user.d.ts
@@ -33,10 +33,31 @@ export interface UserState extends OengusState {
   searches: { [query: string]: Array<User>; };
 }
 
-export type ConnectionPlatform = 'DISCORD'|'TWITCH'|'TWITTER'|''
+// This ended up being kinda social. Move to its own file?
+
+export type ConnectionPlatform =
+  'DISCORD' |
+  'EMAIL' |
+  'FACEBOOK' |
+  'INSTAGRAM' |
+  'PHONE' |
+  'NICO' |
+  'SNAPCHAT' |
+  'SPEEDRUNCOM' |
+  'TWITCH' |
+  'TWITTER';
 
 export interface Connection {
   id: number;
   platform: ConnectionPlatform;
   username: string;
 }
+
+export interface ConnectionMeta {
+  linkBase?: (fragment: string) => string;
+  icon: Array<String>;
+  header?: string;
+  link?: string;
+}
+
+export type ConnectionMetas = Record<ConnectionPlatform, ConnectionMeta>;