How to grab the string from url parameter in HTML5 Export

Godot Version

4.3

Question

I exported my godot game to web (html5) and I want to read map data from a url parameter. So for example we would load the game like: index.html?map-data=map string here.

Here’s what I tried, but it doesn’t work:

func _ready():
	# Check if we're running in a web environment (HTML5 export)
	if Engine.has_singleton("JavaScript"):
		var js = Engine.get_singleton("JavaScript")
		var url = js.call("get_current_url")  # Get the current page URL
		var map_data_from_url = extract_map_data_from_url(url)
		
		if map_data_from_url:
			map_data = map_data_from_url
			if validate_map_data(map_data):
				print("Map data successfully loaded:\n%s" % map_data)
			else:
				print("Error: Invalid map data format.")
		else:
			print("Error: No valid map-data URL parameter found.")
	else:
		print("Error: JavaScript is not available (likely not running in a web environment).")

# Function to extract map data from the URL
func extract_map_data_from_url(url: String) -> String:
	var query_start = url.find("?")
	if query_start == -1:
		return ""  # No query string found
		
	var query_string = url.substr(query_start + 1, url.length() - query_start - 1)
	var params = query_string.split("&")
	
	for param in params:
		var key_value = param.split("=")
		if key_value.size() == 2 and key_value[0] == "map-data":
			return key_value[1]
	
	return ""
1 Like

Not the full solution, but I found something that might lead to such.

in this announcement, they added a JavaScriptObject class and gave us more options including callback shenanigans both ways between Godot and JavaScript. In trying to solve this same problem, I started to make use of JavaScript.get_interface("window") and Godot’s head include section. In the head include, I added this script (please ignore the global user ID variable, I know it’s a terrible idea lol):

<script type="text/javascript">
	const params = new URLSearchParams(document.location.search);
	const UID = parseInt(params.get('user_id'));
</script>

The URLSearchParams(document.location.search) part gets the parameters in the URL. You might be able to get those in Godot with var document = JavaScript.get_interface("document") and using document.location.search somehow, but I went a different direction.

Now, in the export, there is a (potentially global…?) variable named UID that all we need to do is capture inside the game itself. the following code DOES NOT WORK, but I believe I’m onto something here.

# this code doesn't work but I feel like we're getting close here
var window = JavaScript.get_interface("window")
var userid = window.UID

I know it’s not as helpful as you wanted, but does this bring any solutions to mind…?

Figured it out, but it’s kind of a duct tape solution. Worst comes to worst and map_data is the only thing you need from the search params, you can do the following (assuming you add the above script to the export head include):

var window = JavaScript.get_interface("window")
	
var map_data= window.location.search
map_data = map_data.substr(10, map_data.length() - 1)
$info.text = map_data

I ended up finding the solution a while ago actually. I don’t know if it’s good but here’s what I’m doing:

if OS.has_feature('web'):
		# Listen for incoming messages from JavaScript
		map_data = JavaScriptBridge.eval('''
			let params = new URL(document.location).searchParams;
			let mapData = params.get("map-data");  // Retrieve the map-data query parameter
			if (mapData) {
				// Decode the map data to handle special characters properly
				decodeURIComponent(mapData);
			} else {
				"No map data in URL";
			}
		''')

		# Check if map data was successfully retrieved
		print("Map Data from JS: %s" % map_data)

However I’m thinking about changing this to handle post requests instead, as there are apparently situations where the string can be too long in the url for servers to process. Not sure if that’s possible in godot though

1 Like