{"id":22914482,"url":"https://github.com/hernancerm/poc-spring-vue","last_synced_at":"2026-05-06T08:31:33.013Z","repository":{"id":113766286,"uuid":"342745036","full_name":"hernancerm/poc-spring-vue","owner":"hernancerm","description":"Proof of concept of a Java + Spring Boot and Vue application, deployed in Heroku","archived":false,"fork":false,"pushed_at":"2021-05-11T01:58:35.000Z","size":48833,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-29T17:09:19.731Z","etag":null,"topics":["fullstack","spring-boot","starter-project","vue","webapp"],"latest_commit_sha":null,"homepage":"https://poc-spring-vue-heroku.herokuapp.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hernancerm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-27T01:39:57.000Z","updated_at":"2023-03-09T00:42:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"21cda489-a105-4b8a-8c33-d6fd8aa41532","html_url":"https://github.com/hernancerm/poc-spring-vue","commit_stats":null,"previous_names":["hernancerm/poc-spring-vue"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hernancerm/poc-spring-vue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hernancerm%2Fpoc-spring-vue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hernancerm%2Fpoc-spring-vue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hernancerm%2Fpoc-spring-vue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hernancerm%2Fpoc-spring-vue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hernancerm","download_url":"https://codeload.github.com/hernancerm/poc-spring-vue/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hernancerm%2Fpoc-spring-vue/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32684597,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T02:33:58.958Z","status":"ssl_error","status_checked_at":"2026-05-06T02:33:39.611Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fullstack","spring-boot","starter-project","vue","webapp"],"created_at":"2024-12-14T05:15:18.095Z","updated_at":"2026-05-06T08:31:32.994Z","avatar_url":"https://github.com/hernancerm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Proof of concept: Spring Boot and Vue application\r\n\r\n## Executing the project\r\n\r\nYou need:\r\n\r\n- (Required) Java 11\r\n- (Optional) Maven 3\r\n\r\nIf you have Maven installed, on the root of the project run: \r\n\r\n```txt\r\nmvn clean package\r\nmvn -pl backend spring-boot:run\r\n```\r\n\r\n**If you don't have Maven installed**, you can use one of the provided wrappers for your OS. On Windows use mvnw.cmd and on macOS and Linux use mvnw. Example on macOS:\r\n\r\n```txt\r\n./mvnw clean package\r\n./mvnw -pl spring-boot:run\r\n```\r\n\r\nThen open the project: \u003chttp://localhost:8080/\u003e\r\n\r\n## Application's behavior\r\n\r\nOnce the application is up and running, the following is true:\r\n\r\n- Going to `localhost:8080` serves Vue's home page.\r\n- Route navigation through page components (e.g. links) works.\r\n- Route navigation by directly typing in browser nav bar works.\r\n- The frontend can talk with the backend without CORS config.\r\n  \r\nBoth the frontend and the backend exist in the same [origin](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#definition_of_an_origin).\r\n\r\n## Setup overview\r\n\r\nThe project is a two-module Maven project; one sub-module for the backend, another one for the frontend.\r\n\r\nThe idea for having both the frontend and backend in the **same origin** boils down to having the backend serve the SPA's (Single Page Application) entry file (`index.html`) and let the SPA deal with everything frontend related (data fetching, state management, routing, etc.), whilst the backend merely forwards non-API requests to the SPA and attends API requests.\r\n\r\n## How to make Spring Boot serve the SPA\r\n\r\nBy default, when the root URL is visited, Spring Boot serves the following file:\r\n\r\n```txt\r\nsrc/main/resources/public/index.html\r\n```\r\n\r\nBy default, when a Vue application is built, it outputs the following directory:\r\n\r\n```\r\ndist\r\n├── css/\r\n├── img/\r\n├── js/\r\n├── favicon.ico\r\n└── index.html\r\n```\r\n\r\nThe idea is to copy the output of Vue's build into the place where Spring Boot expects to find the `index.html`. This is done with the [`maven-resources-plugin`](https://maven.apache.org/plugins/maven-resources-plugin/) (see the `pom.xml` of the backend sub-module). This plugin does the copying during the `generate-resources` phase, which comes before the `compile` phase. For reference on the Maven phases, see [Lifecycles Reference](https://maven.apache.org/ref/3.6.3/maven-core/lifecycles.html).\r\n\r\nAdditionally, how can the frontend be built by Maven? Otherwise, the frontend would be required to be built through a npm invocation before Maven can use the output. This is done with the [`frontend-maven-plugin`](https://github.com/eirslett/frontend-maven-plugin) (see the `pom.xml` of the frontend sub-module).\r\n\r\n## Heroku configuration\r\n\r\nCreate the following config vars in the settings page of your Heroku app:\r\n\r\n```\r\nBASE_URL=\u003cheroku-url-for-you-app\u003e\r\nMAVEN_CUSTOM_GOALS=clean package\r\n```\r\n\r\nThis config vars are read as environment vars by the application.\r\n\r\n* `BASE_URL` is used by the Spring configuration and the Vue router.\r\n* `MAVEN_CUSTOM_GOALS` tells Heroku how to build the project.\r\n\r\nIn the root of the project, the [Procfile](./Procfile) defines the command used to execute the project. Notice that entire application can be executing through a JAR and that the `heroku` profile is being used.\r\n\r\nHeroku assigns a port to the application to bind to, this is provided by Heroku through the env variable `PORT`. In the Spring configuration this env var is read to configure execution. \r\n\r\n## Other configurations\r\n\r\n- **Vue's dev server**. With the setup described above, running the project requires Maven to re-build the frontend and re-compile the backend, which can be lengthy. To accelerate frontend development, a dev server is created at `localhost:8081` after running `npm run serve` in the frontend sub-module. **This does require CORS to talk to the backend**, but frontend reload is much faster. CORS is configured in Spring Boot for the dev server (see class [`WebConfiguration`](backend/src/main/java/hercerm/pocspringvue/configuration/WebConfiguration.java)).\r\n- **Spring Boot's route forwarding**. Spring Boot automatically serves `src/main/resources/public/index.html` when the root URL is visited, however it does not automatically delegate routing to Vue. To allow Vue to handle all the routing, forwarding is required for every route except `/index.html` and `api/*` routes. See the class [`FrontendForwarderController`](backend/src/main/java/hercerm/pocspringvue/configuration/FrontendForwarderController.java).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhernancerm%2Fpoc-spring-vue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhernancerm%2Fpoc-spring-vue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhernancerm%2Fpoc-spring-vue/lists"}