diff --git a/Gemfile b/Gemfile
index f3f79b89..48cddfbe 100644
--- a/Gemfile
+++ b/Gemfile
@@ -107,6 +107,7 @@ gem 'acts_as_follower', '0.1.1'
 gem 'color'
 gem 'createsend'
 gem 'fog'
+gem 'friendly_id', '4.0.10.1'
 gem 'geocoder'
 gem 'hashie'
 gem 'linkedin'
diff --git a/Gemfile.lock b/Gemfile.lock
index 11a90fa8..92f96050 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -258,6 +258,8 @@ GEM
       dotenv (~> 0.11.1)
       thor (~> 0.19.1)
     formatador (0.2.5)
+    friendly_id (4.0.10.1)
+      activerecord (>= 3.0, < 4.0)
     fssm (0.2.10)
     fukuzatsu (0.9.16)
       ephemeral
@@ -739,6 +741,7 @@ DEPENDENCIES
   flog
   fog
   foreman
+  friendly_id (= 4.0.10.1)
   fukuzatsu
   fuubar (= 2.0.0.rc1)
   geocoder
diff --git a/app/assets/javascripts/backbone/routers/ProtipRouter.js.coffee b/app/assets/javascripts/backbone/routers/ProtipRouter.js.coffee
index c0a7abe8..d3a9d3ae 100644
--- a/app/assets/javascripts/backbone/routers/ProtipRouter.js.coffee
+++ b/app/assets/javascripts/backbone/routers/ProtipRouter.js.coffee
@@ -4,14 +4,11 @@ window.ProtipRouter = Backbone.Router.extend(
     '*path': 'closeProtip'
 
   fetchProtip: (id)->
-    if(id.match(/^[\dA-Z\-_]{6}$/i))
       $.ajax '/p/' + id,
         type: 'GET'
         data:
           mode: 'popup'
         dataType: 'script'
-    else
-      @.closeProtip()
 
   closeProtip: ->
     $('#x-active-preview-pane').remove()
diff --git a/app/controllers/protips_controller.rb b/app/controllers/protips_controller.rb
index d19b16a9..48f699ca 100644
--- a/app/controllers/protips_controller.rb
+++ b/app/controllers/protips_controller.rb
@@ -135,6 +135,8 @@ def show
                   end
 
     return redirect_to protip_missing_destination, notice: "The pro tip you were looking for no longer exists" if @protip.nil?
+    return redirect_to protip_path(@protip.public_id<<'/'<<@protip.friendly_id, :p => params[:p], :q => params[:q]) if params[:slug]!=@protip.friendly_id
+    
     @comments    = @protip.comments
     @reply_to    = show_params[:reply_to]
     @next_protip = Protip.search_next(show_params[:q], show_params[:t], show_params[:i], show_params[:p]) if is_admin?
diff --git a/app/models/protip.rb b/app/models/protip.rb
index 33f61265..586700e3 100644
--- a/app/models/protip.rb
+++ b/app/models/protip.rb
@@ -7,6 +7,9 @@
 require 'search'
 
 class Protip < ActiveRecord::Base
+  extend FriendlyId
+  friendly_id :slug_format, :use => :slugged
+    
   include Featurable
   # TODO: Break out the various responsibilities on the Protip into modules/concerns.
 
@@ -951,7 +954,11 @@ def matching_jobs
   def to_html
     CFM::Markdown.render self.body
   end
-
+  
+  def slug_format
+    "#{title}"
+  end
+  
   protected
   def check_links
     errors[:body] << "one or more of the links are invalid or not publicly reachable/require login" unless valid_links?
@@ -969,7 +976,7 @@ def adjust_like_value(user, like_value)
   def analyze_spam
     AnalyzeSpamJob.perform_async({ id: id, klass: self.class.name })
   end
-
+  
 end
 
 # == Schema Information
diff --git a/config/routes.rb b/config/routes.rb
index 5aa68c27..7dd79422 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -287,8 +287,9 @@
   get '/jobs(/:location(/:skill))' => 'opportunities#index', as: :jobs
   get '/jobs-map' => 'opportunities#map', as: :jobs_map
 
-  resources :protips, :path => '/p', :constraints => {id: /[\dA-Z\-_]{6}/i} do
+  resources :protips, :path => '/p' do
     collection do
+      get ':id/:slug' => 'protips#show', as: :slug, :constraints => {:slug => /(?!.*?edit).*/} 
       get 'random'
       get 'search' => 'protips#search', as: :search
       post 'search' => 'protips#search'
diff --git a/db/migrate/20141015182230_add_slug_to_protips.rb b/db/migrate/20141015182230_add_slug_to_protips.rb
new file mode 100644
index 00000000..882b8494
--- /dev/null
+++ b/db/migrate/20141015182230_add_slug_to_protips.rb
@@ -0,0 +1,6 @@
+class AddSlugToProtips < ActiveRecord::Migration
+  def change
+    add_column :protips, :slug, :string
+    add_index :protips, :slug
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index e6738cdb..e460520d 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20140807214719) do
+ActiveRecord::Schema.define(:version => 20141015182230) do
 
   add_extension "citext"
 
@@ -254,9 +254,11 @@
     t.float    "boost_factor",        :default => 1.0
     t.integer  "inappropriate",       :default => 0
     t.integer  "likes_count",         :default => 0
+    t.string   "slug"
   end
 
   add_index "protips", ["public_id"], :name => "index_protips_on_public_id"
+  add_index "protips", ["slug"], :name => "index_protips_on_slug"
   add_index "protips", ["user_id"], :name => "index_protips_on_user_id"
 
   create_table "purchased_bundles", :force => true do |t|
diff --git a/lib/tasks/generate_protip_slugs.rake b/lib/tasks/generate_protip_slugs.rake
new file mode 100644
index 00000000..27fcc0b5
--- /dev/null
+++ b/lib/tasks/generate_protip_slugs.rake
@@ -0,0 +1,10 @@
+desc 'Generate slugs for existing protips'
+task :generate_protip_slugs => :environment do
+  begin
+    Protip.all.each do |pt|
+      pt.save
+    end
+  rescue => e
+    puts "Rake task protip slugs failed: #{e}"
+  end
+end
diff --git a/spec/controllers/protips_controller_spec.rb b/spec/controllers/protips_controller_spec.rb
index ab2de649..999dd110 100644
--- a/spec/controllers/protips_controller_spec.rb
+++ b/spec/controllers/protips_controller_spec.rb
@@ -49,10 +49,20 @@ def valid_session
   #   end
   # end
 
-  describe "GET show" do
-    it "assigns the requested protip as @protip" do
+  describe "GET show using public_id" do
+    it "redirects to GET show using slug" do
       protip = Protip.create! valid_attributes
+      protip.save
       get :show, {id: protip.to_param}, valid_session
+      expect(response).to redirect_to slug_protips_path(protip,protip.friendly_id)
+    end
+  end
+  
+  describe "GET show using slug" do
+    it "assigns the requested protip as @protip" do
+      protip = Protip.create! valid_attributes
+      protip.save
+      get :show, {id: protip.public_id, slug: protip.friendly_id}, valid_session
       expect(assigns(:protip)).to eq(protip)
     end
   end