title: How to integrate an Angular 2 app into a Django app
body: <p>I've been following this <a href="https://angular.io/docs/ts/latest/tutorial/" rel="nofollow noreferrer">Tour of Heroes</a> tutorial. I have a Django app whose structure can be simplified as follows</p>
  
  <pre><code>apps/my_app/migrations/
  apps/my_app/__init__.py
  apps/my_app/urls.py
  apps/my_app/views.py
  
  frontend_stuff/js/    javascripts here
  frontend_stuff/css/   css here
  </code></pre>
  
  <p>the hero app has the following structure:</p>
  
  <pre><code>heroes/app/           contains all the .ts and .html files
  heroes/node_modules/  angular2 and other libraries
  heroes/styles.css     css file
  heroes/index.html
  heroes/package.json and other config files
  </code></pre>
  
  <p>currently i've built an API using Django View that handles Http Request via URL and returns JSON. But where/how should I place this Angular app into the current Django app, and how can I load the Angular app into the browser upon the initial GET request to Django backend?</p>
  
  <p>EDIT: more specific questions on loading HTML and JS:</p>
  
  <p>Since Angular 2 uses <code>Component</code> and the templates are rendered by Angular rather than Django, how to let Angular "access" those html?  @Luis mentioned that those files should be placed inside the static folder, but <code>{% static %}</code> is Django syntax which wouldn't make sense to Angular.</p>
  
  <p>Similarly, I suppose <code>app/main</code> (shown below) should also be placed in static folder. But how to refer to the location inside Angular? Thanks!</p>
  
  <pre><code>  System.import('app/main')
          .then(null, console.error.bind(console));
  </code></pre>
  
  <p>UPDATE:
  i followed <a href="https://stackoverflow.com/a/35815803/3974213">this answer</a> and used <code>/static/js/my_app/main</code> and it's "mostly" loading fine now. so far all my js files seem to be loaded; but the console log shows that some angular files give 404 error before loading successfully. error as shown below:</p>
  
  <pre><code>system.src.js:1085 GET http://localhost:8000/static/js/node_modules/angular2/src/platform/browser.js 404 (NOT FOUND)fetchTextFromURL @ system.src.js:1085(anonymous function) @ system.src.js:1646ZoneAwarePromise @ angular2-polyfills.js:589(anonymous function) @ system.src.js:1645(anonymous function) @ system.src.js:2667(anonymous function) @ system.src.js:3239(anonymous function) @ system.src.js:3506(anonymous function) @ system.src.js:3888(anonymous function) @ system.src.js:4347(anonymous function) @ system.src.js:4599(anonymous function) @ system.src.js:337ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
  system.src.js:1085 XHR finished loading: GET "http://localhost:8000/static/js/rbac/app/rbac.service.js".fetchTextFromURL @ system.src.js:1085(anonymous function) @ system.src.js:1646ZoneAwarePromise @ angular2-polyfills.js:589(anonymous function) @ system.src.js:1645(anonymous function) @ system.src.js:2667(anonymous function) @ system.src.js:3239(anonymous function) @ system.src.js:3506(anonymous function) @ system.src.js:3888(anonymous function) @ system.src.js:4347(anonymous function) @ system.src.js:4599(anonymous function) @ system.src.js:337ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
  system.src.js:1085 XHR finished loading: GET "http://localhost:8000/static/js/node_modules/angular2/src/platform/browser.js".fetchTextFromURL @ system.src.js:1085(anonymous function) @ system.src.js:1646ZoneAwarePromise @ angular2-polyfills.js:589(anonymous function) @ system.src.js:1645(anonymous function) @ system.src.js:2667(anonymous function) @ system.src.js:3239(anonymous function) @ system.src.js:3506(anonymous function) @ system.src.js:3888(anonymous function) @ system.src.js:4347(anonymous function) @ system.src.js:4599(anonymous function) @ system.src.js:337ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
  angular2-polyfills.js:332 Error: Error: XHR error (404 NOT FOUND) loading http://localhost:8000/static/js/node_modules/angular2/src/platform/browser.js(…)ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
  system.src.js:1085 GET http://localhost:8000/static/js/node_modules/angular2/src/http.js 404 (NOT FOUND)
  </code></pre>
  
  <p>Update: the above error was due to incorrect path in System Confing. Now everything loads with the following config:</p>
  
  <pre><code>&lt;script&gt;
    System.config({
      defaultJSExtensions: true,
      map:{
        angular2: '/static/js/node_modules/angular2',
        rxjs: '/static/js/node_modules/rxjs'
      },
      packages: {
        app: {
          format: 'register',
          defaultExtension: 'js'
        }
      }
    });
    System.import('/static/apps/my_app/app/main')
          .then(null, console.error.bind(console));
  &lt;/script&gt;
  </code></pre>