Serve one HTML document with Content-Type: text/html; charset=utf-8, its title and description in the document head, and readable content in the body. This Mac walkthrough builds a synthetic page and checks that one response carries all three.
The task is to prepare a browser-readable public document, using a local preview before transferring the same structure to a publishing system. The example contains only invented text about paper shapes and requires no external assets.
What belongs in a single typed HTTP response?
“Typed” means that the response declares its media type. The Content-Type field tells the recipient the representation’s format and intended processing. Here, that format is HTML. It does not provide a field-by-field application schema. RFC 9110, section 8.3
An HTTP/1.1 response has a status line, header fields, a blank line, and an optional body. Consequently, you can send transport metadata in the headers and the complete document in the body without creating a separate metadata request. RFC 9112, section 2.1
For this publishing task, use the following placement guide. It separates information describing the HTTP representation from information describing the page.
| Information | Location | Example |
|---|---|---|
| Representation format and encoding | HTTP header | Content-Type: text/html; charset=utf-8 |
| Document title | HTML head | <title>Paper Shapes: Circle and Square</title> |
| Page summary | HTML head | <meta name="description" content="A short guide to arranging paper circles and squares."> |
| Reader-facing content | HTML body | Heading, introduction, and arrangement instructions |
WHATWG defines the title element as the document’s title or name and the description metadata value as a description of the page. Use one title and at most one description declaration. Their placement inside the HTML document means that content and descriptive metadata travel together. HTML Standard: Document metadata
How do you build a working preview on a Mac?
Open Terminal and check the available commands:
python3 --version
curl --version
The program below requires Python 3.7 or later and uses only its standard library. If python3 is unavailable, follow the official macOS installation instructions and then reopen Terminal. Python’s documentation describes both the installer and invoking python3 from a terminal. Using Python on macOS
Paste the complete block below into Terminal, including the opening command and final PY line. This runs the program directly; it does not create or overwrite a file. Leave this terminal window running while checking the page.
python3 - <<'PY'
from html import escape
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
TITLE = "Paper Shapes: Circle and Square"
SUMMARY = "A short guide to arranging paper circles and squares."
PAGE = f"""<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{escape(TITLE)}</title>
<meta name="description" content="{escape(SUMMARY, quote=True)}">
</head>
<body>
<main>
<h1>{escape(TITLE)}</h1>
<p>{escape(SUMMARY)}</p>
<h2>Try a simple arrangement</h2>
<p>Place one paper circle beside one paper square.</p>
<p>Switch their positions — then compare the two arrangements.</p>
</main>
</body>
</html>
""".encode("utf-8")
class Handler(BaseHTTPRequestHandler):
protocol_version = "HTTP/1.1"
def respond(self, include_body):
if self.path != "/paper-shapes":
self.send_error(404, "Page not found")
return
self.send_response(200)
self.send_header("Content-Type", "text/html; charset=utf-8")
self.send_header("Content-Length", str(len(PAGE)))
self.end_headers()
if include_body:
self.wfile.write(PAGE)
def do_GET(self):
self.respond(True)
def do_HEAD(self):
self.respond(False)
if __name__ == "__main__":
with ThreadingHTTPServer(("127.0.0.1", 8000), Handler) as server:
print("Preview: http://127.0.0.1:8000/paper-shapes", flush=True)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
PY
The handler uses Python’s documented response methods: send_response() starts the response, send_header() adds fields, and end_headers() completes the header section before body bytes are written. Python HTTP server documentation
The example deliberately defines TITLE and SUMMARY once. Those values supply both metadata and visible text, making this small document easier to revise consistently. For a longer page, the description can differ from the opening paragraph while accurately summarizing the same subject.
The page is encoded before calculating its length. HTTP defines Content-Length in octets, or bytes; counting characters would give the wrong result for this example’s em dash. RFC 9110, section 8.6
How do you verify that content and metadata arrived together?
Open a second Terminal window and run this command. It makes a normal document request and displays both response headers and content:
curl -i --max-time 10 http://127.0.0.1:8000/paper-shapes
The -i option includes response headers in the same output stream as the body. The time limit bounds the transfer to ten seconds. These options are documented in the curl command-line manual.
Check the output in order:
- The status line should report
200 OK. - A single
Content-Typefield should declaretext/html; charset=utf-8. - After the header section’s blank line, the HTML should contain the title and description.
- The same body should contain the paper-shape instructions.
- The em dash should appear correctly in the decoded text.
Next, enter http://127.0.0.1:8000/paper-shapes in Safari’s address bar. The visible page should show its heading, summary, and instructions. The description declaration is metadata; its presence is checked in the returned markup rather than inferred from how the page looks.
You can also check the header-only path:
curl -I --max-time 10 http://127.0.0.1:8000/paper-shapes
This sends HEAD, so it cannot verify that the body contains the title or description. A HEAD response omits content while describing the corresponding representation; use the earlier GET check to inspect the actual document. RFC 9110, section 8.2
If the preview does not work, use the symptom to choose the next action:
| Symptom | Next action |
|---|---|
| Startup reports that the address is already in use | Change 8000 to 8001 in the program, rerun it, and use 8001 in every preview command. |
| The request reports a connection failure | Check that the first terminal still shows the running preview and that the ports match. |
The response is 404 |
Use exactly /paper-shapes; this example does not accept a trailing slash or query string. |
| The browser still shows an earlier version | Stop the program with Control-C, rerun the edited block, and reload. |
| The heading looks right but metadata is missing | Inspect the GET output and confirm that the declarations occur inside the document head. |
What can Google Search use from this response?
A descriptive title, an accurate description, and useful visible text give Google documented inputs for presenting a page. Google lists the title element, the main visual title, heading elements, and other sources among its inputs for automatically generating title links. Keep those signals consistent with the document’s subject. Influencing your title links in search results
Google primarily generates snippets from page content and sometimes uses the meta description when it describes the page more accurately. Different searches can produce different snippets. Treat the description as a useful summary rather than a fixed search-result caption. Control your snippets in search results
For the synthetic example, the description promises a short arrangement guide, and the body supplies that guide. When replacing the sample text, check this relationship explicitly: someone reading only the description should form an accurate expectation of the page.
Adding custom metadata names does not establish support for them. Google states that it ignores meta tags it does not support. Use its documented fields for search-facing metadata; a field invented for your own application needs a separately defined consumer. Meta tags and attributes that Google supports
How does the preview become a public publishing pattern?
The local address in this walkthrough is a desktop preview, not a published page. Python also documents that http.server is not recommended for production. Transfer the HTML structure and response requirements to your publishing system rather than using this demonstration as the public hosting service. Python HTTP server documentation
If you use a content management system, look for its documented page-title and meta-description controls. Google notes that a CMS may provide search settings instead of direct HTML editing. Map those controls to the fields demonstrated here, then inspect the resulting document response. Google’s guidance on adding meta descriptions
HTTP does support multipart representations, but that is a different packaging choice. For this browser-readable document task, the supported HTML structure already accommodates content and document metadata in one representation. Choosing multipart would introduce a consumer-processing requirement that this walkthrough does not need. RFC 9110, section 8.3.3
Your completion check is concrete: one successful document request returns the correct media type, a complete HTML body, an accurate title and description, and the text readers came to use. Apply that check to the eventual public response as well as the local preview, so the publishing system’s output matches the document you prepared.
Sources
- RFC 9110: HTTP Semantics — IETF / RFC Editor.
- RFC 9112: HTTP/1.1 — IETF / RFC Editor.
- HTML Standard: Document metadata — WHATWG.
- Using Python on macOS — Python Software Foundation.
- http.server — HTTP servers — Python Software Foundation.
- curl — How To Use — curl.
- Influencing Title Links in Google Search — Google Search Central.
- How to Write Meta Descriptions — Google Search Central.
- Meta Tags and Attributes that Google Supports — Google Search Central.