Skip to main content
This guide shows how to connect a local Flask backend (Image Optimizer) to a React frontend: configuring CORS, returning binary image data from Flask, and displaying both original and optimized images (with file sizes and reduction percentage) in React. It assumes both apps run locally during development. Keywords: Flask, React, CORS, image optimization, binary response, send_file, FormData, URL.createObjectURL Prerequisites
  • Flask Image Optimizer runs locally (e.g., http://127.0.0.1:5000).
  • React app runs locally (e.g., http://localhost:5173).

1) Run the Flask app

Activate your Python virtual environment and start Flask:
By default, the Flask development server starts on http://127.0.0.1:5000.

2) Handle CORS (Cross-Origin Resource Sharing)

When the React dev server uses a different origin (for example http://localhost:5173), the browser will block cross-origin fetch requests unless the backend allows that origin. Install Flask-CORS in your virtual environment:
Add CORS configuration to your Flask application factory (__init__.py or wherever you create the app). The following example allows requests only from your dev frontend origin and restricts methods and headers used by the client:
Allowing only specific origins is safer than CORS(app) which opens all origins. In production, set the allowed origin(s) via environment variables so you can update them without changing code.
Restart Flask after changing the configuration.

3) Verify the endpoint path

Confirm your React client posts to the exact route your Flask app expects. If your Flask route is /upload, make sure the client sends the request to http://127.0.0.1:5000/upload. Posting to the wrong path (e.g., /) results in a 404. Quick manual test using curl or Postman:

4) React: POST image and handle binary (Blob) response

Below is an example App.jsx demonstrating best practices:
  • Build FormData with the selected file and other form values (e.g., quality).
  • Send the FormData using fetch to the Flask /upload endpoint.
  • Parse the response as a Blob because Flask returns raw image bytes.
  • Use URL.createObjectURL(blob) to display the optimized image in the browser.
  • Track and display original and optimized file sizes, and revoke object URLs to prevent memory leaks.
Replace or adapt your existing App.jsx with this pattern.
Notes on the React client
  • Use response.blob() because the Flask backend returns binary image bytes. Parsing as JSON will cause a SyntaxError.
  • Display the returned image by creating an object URL with URL.createObjectURL(blob).
  • Use file.size for the original file and blob.size for the optimized result.
  • Revoke object URLs in useEffect cleanup to avoid memory leaks.

5) Backend: return binary image bytes (not JSON)

Ensure the Flask endpoint accepts multipart/form-data, processes the image (for example, using Pillow), and returns raw image bytes with the correct Content-Type header (e.g., image/jpeg or image/png). If you intend the client to use the response as an image, return the binary stream — do not wrap the image bytes in JSON. Example minimal route (conceptual):
Tips
  • Set the correct mimetype to match the returned bytes.
  • If you need to support multiple output formats, choose the format dynamically and set mimetype accordingly.
  • When debugging, verify the response headers and payload with Postman or curl to confirm raw bytes are returned.

6) Avoid hard-coding the API URL

Do not embed the API base URL in application code for production. Use environment variables or a configuration approach.
Store the backend API URL in an environment variable (e.g., VITE_API_URL with Vite) and reference it in the frontend. This simplifies switching between development, staging, and production.
Example using Vite:
  • Create .env (not committed) with VITE_API_URL=http://127.0.0.1:5000.
  • Use it in React: const api = import.meta.env.VITE_API_URL || 'http://127.0.0.1:5000';

Quick troubleshooting table

Final checklist before deployment

  • Start and test the Flask server (flask run) and verify /upload with Postman or curl.
  • Start React dev server (npm run dev) and test the UI upload flow.
  • Replace all local URLs with environment-managed values for production.
  • Lock down CORS to only the production frontend origin(s).
  • Keep documentation up-to-date with any structural or endpoint changes.
Useful links and references
A screenshot of a GitHub repository page titled "Super-Image-Optimizer" in dark mode. It shows the repo file list and README section on the left with project details (license, languages, releases) in the right-hand sidebar.

Watch Video