diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt
index 85632d6e83..1da65b3002 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt
@@ -25,7 +25,12 @@ import android.net.Uri
  */
 sealed class PermalinkData {
 
-    data class RoomLink(val roomIdOrAlias: String, val isRoomAlias: Boolean, val eventId: String?) : PermalinkData()
+    data class RoomLink(
+            val roomIdOrAlias: String,
+            val isRoomAlias: Boolean,
+            val eventId: String?,
+            val viaParameters: List<String>
+    ) : PermalinkData()
 
     data class UserLink(val userId: String) : PermalinkData()
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt
index dd6847f1e3..d741367376 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt
@@ -19,6 +19,10 @@ package org.matrix.android.sdk.api.session.permalinks
 
 import android.net.Uri
 import org.matrix.android.sdk.api.MatrixPatterns
+import java.io.UnsupportedEncodingException
+import java.net.URLEncoder
+import java.util.ArrayList
+import java.util.Collections
 
 /**
  * This class turns an uri to a [PermalinkData]
@@ -40,14 +44,13 @@ object PermalinkParser {
         if (!uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE)) {
             return PermalinkData.FallbackLink(uri)
         }
-
         val fragment = uri.fragment
         if (fragment.isNullOrEmpty()) {
             return PermalinkData.FallbackLink(uri)
         }
-
         val indexOfQuery = fragment.indexOf("?")
         val safeFragment = if (indexOfQuery != -1) fragment.substring(0, indexOfQuery) else fragment
+        val viaQueryParameters = fragment.getViaParameters(indexOfQuery)
 
         // we are limiting to 2 params
         val params = safeFragment
@@ -65,17 +68,58 @@ object PermalinkParser {
                 PermalinkData.RoomLink(
                         roomIdOrAlias = identifier,
                         isRoomAlias = false,
-                        eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) }
+                        eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) },
+                        viaParameters = viaQueryParameters
                 )
             }
             MatrixPatterns.isRoomAlias(identifier) -> {
                 PermalinkData.RoomLink(
                         roomIdOrAlias = identifier,
                         isRoomAlias = true,
-                        eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) }
+                        eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) },
+                        viaParameters = viaQueryParameters
                 )
             }
             else                                   -> PermalinkData.FallbackLink(uri)
         }
     }
+
+    private fun String.getViaParameters(indexOfQuery: Int): List<String> {
+        val query = try {
+            substring(indexOfQuery + 1)
+        } catch (e: IndexOutOfBoundsException) {
+            return emptyList()
+        }
+        val encodedKey = try {
+            URLEncoder.encode("via", "UTF-8")
+        } catch (e: UnsupportedEncodingException) {
+            return emptyList()
+        }
+        val values = ArrayList<String>()
+        var start = 0
+        do {
+            val nextAmpersand = query.indexOf('&', start)
+            val end = if (nextAmpersand != -1) nextAmpersand else query.length
+            var separator = query.indexOf('=', start)
+            if (separator > end || separator == -1) {
+                separator = end
+            }
+            if (separator - start == encodedKey.length
+                    && query.regionMatches(start, encodedKey, 0, encodedKey.length)) {
+                if (separator == end) {
+                    values.add("")
+                } else {
+                    values.add(Uri.decode(query.substring(separator + 1, end)))
+                }
+            }
+
+            // Move start to end of name.
+            start = if (nextAmpersand != -1) {
+                nextAmpersand + 1
+            } else {
+                break
+            }
+        } while (true)
+        return Collections.unmodifiableList(values)
+    }
 }
diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt
index cd26027f94..4ca16888a5 100644
--- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt
+++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt
@@ -56,7 +56,25 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
         if (deepLink == null) {
             return Single.just(false)
         }
-        return when (val permalinkData = PermalinkParser.parse(deepLink)) {
+        return Single
+                .fromCallable {
+                    PermalinkParser.parse(deepLink)
+                }
+                .subscribeOn(Schedulers.computation())
+                .observeOn(AndroidSchedulers.mainThread())
+                .flatMap { permalinkData ->
+                    handlePermalink(permalinkData, context, navigationInterceptor, buildTask)
+                }
+                .onErrorReturnItem(false)
+    }
+
+    private fun handlePermalink(
+            permalinkData: PermalinkData,
+            context: Context,
+            navigationInterceptor: NavigationInterceptor?,
+            buildTask: Boolean
+    ): Single<Boolean> {
+        return when (permalinkData) {
             is PermalinkData.RoomLink     -> {
                 permalinkData.getRoomId()
                         .observeOn(AndroidSchedulers.mainThread())
@@ -66,8 +84,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
                                 openRoom(
                                         context = context,
                                         roomId = roomId,
-                                        roomAlias = permalinkData.getRoomAliasOrNull(),
-                                        eventId = permalinkData.eventId,
+                                        permalinkData = permalinkData,
                                         buildTask = buildTask
                                 )
                             }
@@ -87,7 +104,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
             is PermalinkData.FallbackLink -> {
                 Single.just(false)
             }
-        }.onErrorReturnItem(false)
+        }
     }
 
     private fun PermalinkData.RoomLink.getRoomId(): Single<Optional<String>> {
@@ -110,13 +127,20 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
     /**
      * Open room either joined, or not
      */
-    private fun openRoom(context: Context, roomId: String?, roomAlias: String?, eventId: String?, buildTask: Boolean) {
+    private fun openRoom(
+            context: Context,
+            roomId: String?,
+            permalinkData: PermalinkData.RoomLink,
+            buildTask: Boolean
+    ) {
         val session = activeSessionHolder.getSafeActiveSession() ?: return
         if (roomId == null) {
             context.toast(R.string.room_error_not_found)
             return
         }
         val roomSummary = session.getRoomSummary(roomId)
+        val eventId = permalinkData.eventId
+        val roomAlias = permalinkData.getRoomAliasOrNull()
         return when {
             roomSummary?.membership?.isActive().orFalse() -> {
                 navigator.openRoom(context, roomId, eventId, buildTask)
@@ -128,7 +152,8 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
                         roomAlias = roomAlias ?: roomSummary?.canonicalAlias,
                         roomName = roomSummary?.displayName,
                         avatarUrl = roomSummary?.avatarUrl,
-                        buildTask = buildTask
+                        buildTask = buildTask,
+                        homeServers = permalinkData.viaParameters
                 )
                 navigator.openRoomPreview(context, roomPreviewData)
             }
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt
index d304594474..8bbaa14ab0 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt
@@ -38,7 +38,7 @@ data class RoomPreviewData(
         val topic: String? = null,
         val worldReadable: Boolean = false,
         val avatarUrl: String? = null,
-        val homeServer: String? = null,
+        val homeServers: List<String> = emptyList(),
         val buildTask: Boolean = false
 ) : Parcelable {
     val matrixItem: MatrixItem
@@ -64,7 +64,7 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
                     topic = publicRoom.topic,
                     worldReadable = publicRoom.worldReadable,
                     avatarUrl = publicRoom.avatarUrl,
-                    homeServer = roomDirectoryData.homeServer
+                    homeServers = listOfNotNull(roomDirectoryData.homeServer)
             )
             return newIntent(context, roomPreviewData)
         }
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt
index 04b7c33fb2..900ba537b5 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt
@@ -106,10 +106,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val ini
             Timber.w("Try to join an already joining room. Should not happen")
             return@withState
         }
-        val viaServers = state.homeServer?.let {
-            listOf(it)
-        } ?: emptyList()
-        session.joinRoom(state.roomId, viaServers = viaServers, callback = object : MatrixCallback<Unit> {
+        session.joinRoom(state.roomId, viaServers = state.homeServers, callback = object : MatrixCallback<Unit> {
             override fun onSuccess(data: Unit) {
                 // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data.
                 // Instead, we wait for the room to be joined
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt
index f461225e2d..6816e54481 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt
@@ -24,10 +24,9 @@ data class RoomPreviewViewState(
         val roomId: String = "",
         val roomAlias: String? = null,
         /**
-         * The server name (might be null)
-         * Set null when the server is the current user's home server.
+         * Can be empty when the server is the current user's home server.
          */
-        val homeServer: String? = null,
+        val homeServers: List<String> = emptyList(),
         // Current state of the room in preview
         val roomJoinState: JoinState = JoinState.NOT_JOINED,
         // Last error of join room request
@@ -37,6 +36,6 @@ data class RoomPreviewViewState(
     constructor(args: RoomPreviewData) : this(
             roomId = args.roomId,
             roomAlias = args.roomAlias,
-            homeServer = args.homeServer
+            homeServers = args.homeServers
     )
 }