Local Development
When developing an extension with a localhost server, you’ll need to serve files over HTTPS with CORS headers. This page covers the setup.
Why HTTPS?
Section titled “Why HTTPS?”SketchUp for Web runs on HTTPS. Browsers block “mixed content” — an HTTPS page loading resources from HTTP. So your local server needs SSL too.
Creating SSL certificates
Section titled “Creating SSL certificates”We recommend mkcert for generating locally-trusted certificates. It’s simple and avoids browser security warnings.
Install mkcert, then generate a certificate:
mkcert -installmkcert -key-file su-extension-key.pem -cert-file su-extension.pem localhost 127.0.0.1 ::1This creates two files:
su-extension.pem— the certificatesu-extension-key.pem— the private key
Python CORS server
Section titled “Python CORS server”Here’s a simple Python server that handles SSL and CORS headers. Save it as server.py:
#!/usr/bin/env python3"""Simple HTTPS server with CORS headers for JSA extension development."""
import http.serverimport sslimport sys
from http.server import HTTPServer, SimpleHTTPRequestHandler
class CORSRequestHandler(SimpleHTTPRequestHandler): def end_headers(self): self.send_header('Access-Control-Allow-Origin', '*') self.send_header('Access-Control-Allow-Methods', 'GET') self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate') return super(CORSRequestHandler, self).end_headers()
def serve(host, port, cert_path, privatekey_path): context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain(certfile=cert_path, keyfile=privatekey_path, password='') server_address = (host, port) httpd = http.server.HTTPServer(server_address, CORSRequestHandler) httpd.socket = context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever()
if __name__ == '__main__': if len(sys.argv) < 4: print(f'Usage:\n {sys.argv[0]} <port> <PEM certificate file> <private key file>') sys.exit()
PORT = int(sys.argv[1]) CERT_FPATH = sys.argv[2] PRIVKEY_FPATH = sys.argv[3]
serve('localhost', PORT, CERT_FPATH, PRIVKEY_FPATH)Run it from the directory containing your extension files:
python3 server.py 9000 su-extension.pem su-extension-key.pemYour extension is now available at https://localhost:9000/.
CORS troubleshooting
Section titled “CORS troubleshooting”If your extension’s icons or assets aren’t loading, it’s likely a CORS issue. The Python server above adds the necessary headers, but if you’re using a different server, make sure it sends:
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GETFor more details, see the MDN CORS guide.