diff --git a/assets/js/ProfilePage.jsx b/assets/js/ProfilePage.jsx
index 2a5e49db6c536369336f21f84f9ed6c1beb0c9ee..f6ab779ca47c1f8c370924d33742584a995b458d 100644
--- a/assets/js/ProfilePage.jsx
+++ b/assets/js/ProfilePage.jsx
@@ -29,6 +29,7 @@ export default class ProfilePage extends React.Component {
       dateOfBirth: '',
       resume: '',
       phone_number: '',
+      portfolio_link: '',
       show_transcript: '',
       photo: '',
       age: '',
@@ -45,6 +46,7 @@ export default class ProfilePage extends React.Component {
         region: '',
         skills: '',
         resume: '',
+        portfolio_link: '',
         show_transcript: '',
         volunteer: '',
         intro: '',
@@ -93,6 +95,7 @@ export default class ProfilePage extends React.Component {
         cityOfBirth: data.birth_place,
         dateOfBirth: this.parseIndonesianDateFormat(data.birth_date),
         phone_number: data.phone_number,
+        portfolio_link: data.portfolio_link,
         photo: data.photo,
         show_transcript: data.show_transcript,
         acceptedNo: data.accepted_no,
@@ -276,6 +279,16 @@ export default class ProfilePage extends React.Component {
                 name="linkedin_url"
               />
             </Form.Field>
+            <Form.Field>
+              <label htmlFor="portfolio_link">Portfolio Link</label>
+              <input
+                onChange={this.handleChange}
+                placeholder={this.state.portfolio_link === null ? 'https://www.example.com/myproject/' :
+                this.state.portfolio_link}
+                defaultValue={this.state.portfolio_link === null ? null : this.state.portfolio_link}
+                name="portfolio_link"
+              />
+            </Form.Field>
             <Form.Field>
               <label htmlFor="website_url">Website URL</label>
               <input
@@ -436,6 +449,17 @@ export default class ProfilePage extends React.Component {
                     </Grid>
                   </Segment>
 
+                  <Segment basic vertical>
+                    <Grid>
+                      <Grid.Column width={2}>
+                        <Icon name="linkify" size="big" />
+                      </Grid.Column>
+                      <Grid.Column width={13}>
+                        <a href={this.state.portfolio_link}> {this.state.portfolio_link || 'N/A'} </a>
+                      </Grid.Column>
+                    </Grid>
+                  </Segment>
+                  
                   <Segment basic vertical>
                     <Grid>
                       <Grid.Column width={2}>
diff --git a/core/lib/validators.py b/core/lib/validators.py
index 54c9b3f35e69f5bb88dffff0514c453181b4904c..01d28fa0b0c17e57345c2b1c61094d99d007d4e9 100755
--- a/core/lib/validators.py
+++ b/core/lib/validators.py
@@ -44,4 +44,4 @@ def validate_npm(value):
         raise ValidationError(u"NPM must be 10 digits")
     val_string = str(value)
     if sum([3*int(a) for a in val_string[:-1:2]]+[int(a) for a in val_string[1:-1:2]]) % 7 != int(val_string[-1]):
-        raise ValidationError(u"NPM {} has invalid checksum".format(value))
\ No newline at end of file
+        raise ValidationError(u"NPM {} has invalid checksum".format(value))
diff --git a/core/migrations/0014_student_portfolio_link.py b/core/migrations/0014_student_portfolio_link.py
new file mode 100644
index 0000000000000000000000000000000000000000..a02dad41d9639ba4aa47b38a730a4a4c6e9ab71a
--- /dev/null
+++ b/core/migrations/0014_student_portfolio_link.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2019-10-06 10:31
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0013_auto_20170602_1130'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='student',
+            name='portfolio_link',
+            field=models.URLField(blank=True, null=True),
+        ),
+    ]
diff --git a/core/migrations/0020_merge_20191006_2021.py b/core/migrations/0020_merge_20191006_2021.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d7d3284fa5249f3a32e0140c0c37e5079297f05
--- /dev/null
+++ b/core/migrations/0020_merge_20191006_2021.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.17 on 2019-10-06 13:21
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0017_vacancy_amount'),
+        ('core', '0019_merge_20191006_0852'),
+        ('core', '0014_student_portfolio_link'),
+        ('core', '0014_auto_20191004_1340'),
+    ]
+
+    operations = [
+    ]
diff --git a/core/migrations/0048_merge_20191012_0956.py b/core/migrations/0048_merge_20191012_0956.py
new file mode 100644
index 0000000000000000000000000000000000000000..5de42f826bab3b3de2427fbd2262ab57cb47fa9a
--- /dev/null
+++ b/core/migrations/0048_merge_20191012_0956.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.17 on 2019-10-12 02:56
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0047_merge_20191011_0029'),
+        ('core', '0020_merge_20191006_2021'),
+    ]
+
+    operations = [
+    ]
diff --git a/core/migrations/0055_merge_20191012_1043.py b/core/migrations/0055_merge_20191012_1043.py
new file mode 100644
index 0000000000000000000000000000000000000000..971ec999341c2744261f031f4c0bca0ddd3dbcdc
--- /dev/null
+++ b/core/migrations/0055_merge_20191012_1043.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.17 on 2019-10-12 03:43
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0054_merge_20191012_1018'),
+        ('core', '0048_merge_20191012_0956'),
+    ]
+
+    operations = [
+    ]
diff --git a/core/models/accounts.py b/core/models/accounts.py
index 44b37387f534492819be9491ac177661b1b87549..1a66e0debd6afc45524d919e10eb9e71bf3c1686 100644
--- a/core/models/accounts.py
+++ b/core/models/accounts.py
@@ -77,6 +77,7 @@ class Student(models.Model):
     show_transcript = models.BooleanField(default=False)
     self_description = models.CharField(max_length=500, blank=True, db_index=True, null=True)
     photo = models.FileField(upload_to=get_student_photo_file_path, null=True, blank=True, validators=[validate_image_file_extension])
+    portfolio_link = models.URLField(blank=True, null=True)
     linkedin_url = models.URLField(max_length=200,blank=True, null=True)
     website_url = models.URLField(max_length=200,blank=True, null=True)
     region = models.CharField(max_length=30, blank=True, null=True)
diff --git a/core/serializers/accounts.py b/core/serializers/accounts.py
index fbb6d7ae6b5696b12ead17b1424372f8936d00cc..de1e669d08dc2fb636390739745d2e9af889d578 100644
--- a/core/serializers/accounts.py
+++ b/core/serializers/accounts.py
@@ -20,7 +20,7 @@ class StudentSerializer(serializers.ModelSerializer):
     class Meta:
         model = Student
         fields = ['id', 'name', 'user', 'npm', 'resume', 'phone_number', 'gender','birth_place', 'birth_date', 'major', 'batch', \
-                  'show_transcript', 'photo', 'accepted_no', 'linkedin_url', 'region', 'intro', 'website_url', 'student_gpa', 'age','recommendations',
+                  'show_transcript', 'photo', 'accepted_no', 'linkedin_url', 'region', 'intro', 'portfolio_link', 'website_url', 'student_gpa', 'age','recommendations',
                   'latest_work', 'latest_work_desc','read_no', 'volunteer','job_seeking_status', 'skills', 'expected_salary', \
                   'self_description', 'github_url']
 
@@ -53,6 +53,7 @@ class StudentUpdateSerializer(serializers.ModelSerializer):
             'region': instance.region,
             'photo': photo,
             'show_transcript': instance.show_transcript,
+            'portfolio_link': instance.portfolio_link,
             'self_description': instance.self_description,
             'intro': instance.intro,
             'expected_salary': instance.expected_salary,
@@ -76,6 +77,7 @@ class StudentUpdateSerializer(serializers.ModelSerializer):
         instance.region = validated_data.get('region', instance.region)
         instance.photo = validated_data.get('photo', instance.photo)
         instance.user.email = validated_data.get('email', instance.user.email)
+        instance.portfolio_link = validated_data.get('portfolio_link', instance.portfolio_link)
         instance.self_description = validated_data.get('self_description', instance.self_description)
         instance.intro = validated_data.get('intro', instance.intro)
         instance.expected_salary = validated_data.get('expected_salary', instance.expected_salary)
@@ -95,11 +97,10 @@ class StudentUpdateSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = Student
-        fields = ['resume', 'email', 'phone_number', 'gender','photo', 'show_transcript', 'linkedin_url', 'region', 'intro', 'website_url', 'student_gpa',
+        fields = ['resume', 'email', 'phone_number', 'gender','photo', 'show_transcript', 'linkedin_url', 'region', 'intro', 'portfolio_link', 'website_url', 'student_gpa',
                   'recommendations', 'latest_work', 'latest_work_desc', 'volunteer','job_seeking_status', 'skills', 'expected_salary', \
                   'self_description', 'github_url']
 
-
 class CompanyUpdateSerializer(serializers.ModelSerializer):
     def to_representation(self, instance):
         logo = None
diff --git a/core/tests/test_accounts.py b/core/tests/test_accounts.py
index da1eae36a5112dbdaa817deb86090a5b4078c05e..5140b33842321ab84839d63c6eb5c41e955ec7f0 100644
--- a/core/tests/test_accounts.py
+++ b/core/tests/test_accounts.py
@@ -153,7 +153,15 @@ class ProfileUpdateTests(APITestCase):
         self.assertEqual(response.data.get('phone_number'), '08123123123')
 
         url = '/api/students/' + str(student_id) + "/profile/"
+        response = self.client.patch(url, {'portfolio_link': 'https://www.example.com/myproject'}, format='multipart')
+        self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
+        self.assertEqual(response.data.get('portfolio_link'), 'https://www.example.com/myproject')
 
+        url = '/api/students/' + str(student_id) + "/profile/"
+        response = self.client.patch(url, {'portfolio_link': 'asdfghjkl'}, format='multipart')
+        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
+
+        url = '/api/students/' + str(student_id) + "/profile/"
         response = self.client.patch(url, {'self_description': 'I am very happy'}, format='multipart')
         self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
         self.assertEqual(response.data.get('self_description'), 'I am very happy')
diff --git a/kape/files/student-ui-ux-portofolio/266a3cd8-10d5-479d-891d-cf782f8b1041.pdf b/kape/files/student-ui-ux-portofolio/266a3cd8-10d5-479d-891d-cf782f8b1041.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..379cb93fd41385e7ea21e9f02d44b2fb84fd860d
Binary files /dev/null and b/kape/files/student-ui-ux-portofolio/266a3cd8-10d5-479d-891d-cf782f8b1041.pdf differ
diff --git a/kape/files/student-ui-ux-portofolio/35dc3798-9d40-48e7-9ad9-68a8fe22941e.pdf b/kape/files/student-ui-ux-portofolio/35dc3798-9d40-48e7-9ad9-68a8fe22941e.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..379cb93fd41385e7ea21e9f02d44b2fb84fd860d
Binary files /dev/null and b/kape/files/student-ui-ux-portofolio/35dc3798-9d40-48e7-9ad9-68a8fe22941e.pdf differ
diff --git a/kape/files/student-ui-ux-portofolio/42edb36e-8d01-40d9-91cf-b0d277b285d1.pdf b/kape/files/student-ui-ux-portofolio/42edb36e-8d01-40d9-91cf-b0d277b285d1.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..379cb93fd41385e7ea21e9f02d44b2fb84fd860d
Binary files /dev/null and b/kape/files/student-ui-ux-portofolio/42edb36e-8d01-40d9-91cf-b0d277b285d1.pdf differ
diff --git a/kape/files/student-ui-ux-portofolio/89512de6-4b5e-40cf-a1db-852db95b692d.pdf b/kape/files/student-ui-ux-portofolio/89512de6-4b5e-40cf-a1db-852db95b692d.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..379cb93fd41385e7ea21e9f02d44b2fb84fd860d
Binary files /dev/null and b/kape/files/student-ui-ux-portofolio/89512de6-4b5e-40cf-a1db-852db95b692d.pdf differ
diff --git a/requirements.txt b/requirements.txt
index 1c88d9a8b84368998481b916cbeab821bcc372cb..2f71531a4b2f3d4540928e40d42d873c4d72eae9 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -13,4 +13,4 @@ django-rest-swagger
 django-silk
 requests
 requests-mock
-django-filter==1.1.0
+django-filter==1.1.0
\ No newline at end of file