import Url
import Url.Parser exposing ((<?>))
import Url.Parser.Query
"http://example.com/?key=Prefix%3A+Some+text+%2B+Some+words+%3D+Words+%40+%3CLast+word%3E"
|> Url.fromString
|> Maybe.andThen (Url.Parser.parse (Url.Parser.top <?> Url.Parser.Query.string "key"))
--> Just (Just "Prefix: Some text + Some words = Words @ <Last word>")
Test will fail
Just (Just "Prefix: Some text + Some words = Words @ <Last word>")
╷
│ Expect.equal
╵
Just (Just "Prefix:+Some+text+++Some+words+=+Words+@+<Last+word>")
Notice that
encodeURIComponent('Prefix: Some text + Some words = Words @ <Last word>')
//=> 'Prefix%3A%20Some%20text%20%2B%20Some%20words%20%3D%20Words%20%40%20%3CLast%20word%3E'
and indeed, using that as input URL, the test will pass
import Url
import Url.Parser exposing ((<?>))
import Url.Parser.Query
-"http://example.com/?key=Prefix%3A+Some+text+%2B+Some+words+%3D+Words+%40+%3CLast+word%3E"
+"http://example.com/?key=Prefix%3A%20Some%20text%20%2B%20Some%20words%20%3D%20Words%20%40%20%3CLast%20word%3E"
|> Url.fromString
|> Maybe.andThen (Url.Parser.parse (Url.Parser.top <?> Url.Parser.Query.string "key"))
--> Just (Just "Prefix: Some text + Some words = Words @ <Last word>")
So, the workaround is actually to augment Url.fromString
import Url
import Url.Parser exposing ((<?>))
import Url.Parser.Query
"http://example.com/?key=Prefix%3A+Some+text+%2B+Some+words+%3D+Words+%40+%3CLast+word%3E"
+|> String.replace "+" "%20"
|> Url.fromString
|> Maybe.andThen (Url.Parser.parse (Url.Parser.top <?> Url.Parser.Query.string "key"))
--> Just (Just "Prefix: Some text + Some words = Words @ <Last word>")