diff --git a/qml/js/WallaBase.js b/qml/js/WallaBase.js
index 95b9e2d..6c95798 100644
--- a/qml/js/WallaBase.js
+++ b/qml/js/WallaBase.js
@@ -526,6 +526,60 @@ function deleteArticle( server, id )
     );
 }
 
+function uploadNewArticle( props, articleUrl, cb )
+{
+    var url = props.url;
+    if ( url.charAt( url.length - 1 ) !== "/" )
+        url += "/";
+    url += "api/entries.json";
+
+    var params = "url=" + escape( articleUrl );
+
+    var http = new XMLHttpRequest;
+
+    http.onreadystatechange = function() {
+        if ( http.readyState === XMLHttpRequest.DONE ) {
+            var json = null;
+            var err = null;
+
+            if ( http.status === 200 ) {
+                try {
+                    json = JSON.parse( http.responseText );
+                }
+                catch( e ) {
+                    json = null;
+                    err = "failed to parse server response";
+                }
+
+                if ( err !== null )
+                    cb( json, err );
+                else
+                    _embedImages(
+                        json,
+                        function( content ) {
+                            json.content = content;
+                            cb( json, null );
+                        }
+                    )
+            }
+            else {
+                err = "server returned '" + http.statusText + "'";
+            }
+
+            cb( json, err );
+        }
+    };
+
+    http.open( "POST", url, true );
+    http.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
+    http.setRequestHeader( "Content-length", params.length );
+    http.setRequestHeader( "Authorization:", "Bearer " + props.token );
+    http.setRequestHeader( "Accept", "application/json" );
+    http.setRequestHeader( "Connection", "close" );
+
+    http.send( params );
+}
+
 function downloadArticles( props, cb )
 {
     var url = props.url;
diff --git a/qml/pages/ServerPage.qml b/qml/pages/ServerPage.qml
index 118fe7f..b9cbca7 100644
--- a/qml/pages/ServerPage.qml
+++ b/qml/pages/ServerPage.qml
@@ -87,7 +87,99 @@ Page {
         }
     }
 
+    MouseArea {
+        id: addArticleContainer
+        width: parent.width
+        height: listView.height
+        x: 0
+        y: listView.height
+        z: 5
+
+        ParallelAnimation {
+            id: showAddArticleContainer
+
+            PropertyAnimation {
+                target: addArticleContainer
+                property: "y"
+                to: 0
+                duration: 150
+                easing.type: Easing.InOutQuad
+            }
+        }
+
+        ParallelAnimation {
+            id: hideAddArticleContainer
+
+            PropertyAnimation {
+                target: addArticleContainer
+                property: "y"
+                to: listView.height
+                duration: 150
+                easing.type: Easing.InOutQuad
+            }
+        }
+
+        Rectangle {
+            height: addArticleUrl.height + addArticleUrl.anchors.topMargin + addArticlesButtonRow.height
+            width: parent.width
+            anchors.bottom: parent.bottom
+            anchors.left: parent.left
+            color: "black"
+            opacity: 0.9
+        }
+
+        Item {
+            height: addArticleUrl.height + addArticleUrl.anchors.topMargin + addArticlesButtonRow.height
+            width: parent.width
+            anchors.bottom: parent.bottom
+            anchors.left: parent.left
+
+            TextField {
+                id: addArticleUrl
+                width: parent.width
+                anchors.top: parent.top
+                anchors.topMargin: Theme.horizontalPageMargin
+                placeholderText: qsTr( "Article URL" )
+                inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhUrlCharactersOnly
+            }
+
+            Row {
+                id: addArticlesButtonRow
+                anchors.top: addArticleUrl.bottom
+                spacing: 2 * Theme.paddingLarge
+                width: addArticleCancel.width + addArticleConfirm.width + Theme.paddingLarge
+                x: ( parent.width / 2 ) - ( ( 2 * spacing + addArticleCancel.width + addArticleConfirm.width ) / 2 )
+
+                IconButton {
+                    id: addArticleCancel
+                    icon.source: "image://theme/icon-m-dismiss"
+
+                    onClicked: {
+                        addArticleUrl.text = ""
+                        hideAddArticleContainer.start()
+                    }
+                }
+
+                IconButton {
+                    id: addArticleConfirm
+                    icon.source: "image://theme/icon-m-acknowledge"
+
+                    onClicked: {
+                        serverPage.server.uploadArticle(
+                            addArticleUrl.text,
+                            function() {
+                                addArticleUrl.text = ""
+                                hideAddArticleContainer.start()
+                            }
+                        )
+                    }
+                }
+            }
+        }
+    }
+
     SilicaListView {
+        id: listView
         anchors.fill: parent
         spacing: Theme.paddingMedium
         model: articlesModel
@@ -120,6 +212,14 @@ Page {
                     )
                 }
             }
+
+            MenuItem {
+                text: qsTr( "Add article" )
+                onClicked: {
+                    showAddArticleContainer.start()
+                    addArticleUrl.focus = true
+                }
+            }
         }
 
         header: PageHeader {
diff --git a/qml/types/Server.qml b/qml/types/Server.qml
index 8ba86c8..d1ad503 100644
--- a/qml/types/Server.qml
+++ b/qml/types/Server.qml
@@ -169,6 +169,48 @@ Item {
         articlesDownloaded( ret )
     }
 
+    function uploadArticle( articleUrl, cb ) {
+        connect(
+            function( err ) {
+                if ( err !== null ) {
+                    error( qsTr( "Failed to connect to server: " ) + err)
+                }
+                else {
+                    console.debug( "Sending a new article" )
+                    var props = { url: url, token: accessToken }
+                    WallaBase.uploadNewArticle( props, articleUrl, function( content, err ) { onUploadArticleDone( content, err ); cb(); } )
+                }
+            }
+        )
+    }
+
+    function onUploadArticleDone( current, err ) {
+        if ( err !== null ) {
+            error( qsTr( "Failed to upload article: " ) + err )
+        }
+        else {
+            var article = {
+                id: current.id,
+                server: serverId,
+                created: current.created_at,
+                updated: current.updated_at,
+                mimetype: current.mimetype,
+                language: current.language,
+                readingTime: current.reading_time,
+                url: current.url,
+                domain: current.domain_name,
+                archived: current.is_archived,
+                starred: current.is_starred,
+                title: current.title,
+                previewPicture: current.previewPicture,
+                content: current.content
+            }
+            WallaBase.saveArticle( article )
+        }
+
+        articlesDownloaded( [] )
+    }
+
     function toggleArticleStar( article, cb ) {
         connect(
             function( err ) {
diff --git a/translations/harbour-wallaread-fr.ts b/translations/harbour-wallaread-fr.ts
index 99f01e5..84662f5 100644
--- a/translations/harbour-wallaread-fr.ts
+++ b/translations/harbour-wallaread-fr.ts
@@ -8,6 +8,13 @@
         <translation>WallaRead</translation>
     </message>
 </context>
+<context>
+    <name>ImageEmbedRequest</name>
+    <message>
+        <source>Failed to find the image source</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>Server</name>
     <message>
@@ -24,15 +31,19 @@
     </message>
     <message>
         <source>Failed to set star status on article: </source>
-        <translation>Échec de la mise en favoris de l'article : </translation>
+        <translation>Échec de la mise en favoris de l&apos;article : </translation>
     </message>
     <message>
         <source>Failed to set read status on article: </source>
-        <translation>Échec du passage au statut lu de l'article : </translation>
+        <translation>Échec du passage au statut lu de l&apos;article : </translation>
     </message>
     <message>
         <source>Failed to delete article: </source>
-        <translation>Échec de la suppression de l'article : </translation>
+        <translation>Échec de la suppression de l&apos;article : </translation>
+    </message>
+    <message>
+        <source>Failed to upload article: </source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 <context>
@@ -43,7 +54,7 @@
     </message>
     <message>
         <source>No articles saved on this server yet</source>
-        <translation>Aucun article enregistré sur le serveur pour l'instant</translation>
+        <translation>Aucun article enregistré sur le serveur pour l&apos;instant</translation>
     </message>
     <message>
         <source>Deleting</source>
@@ -55,7 +66,7 @@
     </message>
     <message>
         <source>Show only starred articles</source>
-        <translation>Seulement afficher les articles en favoris></translation>
+        <translation>Seulement afficher les articles en favoris&gt;</translation>
     </message>
     <message>
         <source>Show unread articles</source>
@@ -65,6 +76,21 @@
         <source>Show read articles</source>
         <translation>Afficher les articles lus</translation>
     </message>
+    <message>
+        <source>Article URL</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Add article</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ServerSettings</name>
+    <message>
+        <source>Failed to load server settings: </source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>ServerSettingsDialog</name>
diff --git a/translations/harbour-wallaread.ts b/translations/harbour-wallaread.ts
index 509c22a..781bd79 100644
--- a/translations/harbour-wallaread.ts
+++ b/translations/harbour-wallaread.ts
@@ -41,19 +41,15 @@
         <source>Failed to delete article: </source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Failed to upload article: </source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>ServerPage</name>
     <message>
-        <source>Refresh</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <source>No articles saved on this server yet</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <source>Deleting</source>
+        <source>Article URL</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -72,6 +68,22 @@
         <source>Show read articles</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Refresh</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>No articles saved on this server yet</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Deleting</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Add article</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>ServerSettings</name>