Alex Chebotarsky
Alex Chebotarsky

Reputation: 513

How to use Angular with WordPress as headless server on the same domain?

UPDATED QUESTION:

I know I asked it differently before, but actually that was the question. I just need to put together WordPress and Angular so whenever I go to /wp-admin/ I go to wordpress admin, and whenever I go anywhere else it renders Angular app. The problems with that are:

  1. How to remove wordpress templates and always load Angular manifest file? (e.g index.html)
  2. How to create manifest that would be .php file, but load Angular app?
  3. Where to place all Angular files as well as /dist folder?

OLD QUESTION:

Using .htaccess how to rewrite root to use subfolder, but still allow /wp-admin?

I have set up wordpress, and uploaded in it's root directory my angular app, that has path /angular/dist/spa. I need to add rewrite rules to .htaccess so any url goes directly to that subfolder, but /wp-admin/*.

Can't find fully working solution, it either allows whole app to work or admin panel to work.

Here's my default .htaccess:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Also it'd be helpful if you suggest any other idea how to use angular app inside wordpress (with no additional plugins), cuz that's the only way I found, but it feels like there's better ways.

Upvotes: 2

Views: 1982

Answers (2)

Alex Chebotarsky
Alex Chebotarsky

Reputation: 513

First thing first you should put your files in WordPress theme. Which has index.php file so your angular manifest code (index.html) goes there, but with proper links to assets.

For example here's how it might look like after ng build --prod:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Title</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link rel="stylesheet" href="styles.b9ab77151b21dce46d94.css" />
  </head>
  <body>
    <app-root></app-root>
    <script src="runtime.e227d1a0e31cbccbf8ec.js" defer></script>
    <script src="polyfills.a5e98176150f229fcd04.js" defer></script>
    <script src="scripts.c5648532e9a6a23906a1.js" defer></script>
    <script src="main.2965e15bb04f185e6e09.js" defer></script>
  </body>
</html>

The problem with the code above is that files have random hashes after the file name and since we're going to put files in a WordPress theme they are going to be placed at /wp-content/themes/%ThemeName%/dist/.

We need to remove hashing in angular.json:

...
"outputHashing": "none",
...

And add proper paths to assets manually or by adding it to the build command ng build --prod --deploy-url /wp-content/themes/%ThemeName%/dist/.

So our index.html looks like:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Title</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link rel="stylesheet" href="/wp-content/themes/%ThemeName%/dist/styles.css" />
  </head>
  <body>
    <app-root></app-root>
    <script src="/wp-content/themes/%ThemeName%/dist/runtime.js" defer></script>
    <script src="/wp-content/themes/%ThemeName%/dist/polyfills.js" defer></script>
    <script src="/wp-content/themes/%ThemeName%/dist/scripts.js" defer></script>
    <script src="/wp-content/themes/%ThemeName%/dist/main.js" defer></script>
  </body>
</html>

Perfect! Now we need to move that to the WordPress theme index.php:

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
  <head>
    <meta charset="<?php bloginfo('charset'); ?>" />
    <title>Title</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link rel="stylesheet" href="/wp-content/themes/%ThemeName%/dist/styles.css" />
  </head>
  <body <?php body_class(); ?>>
    <app-root></app-root>
    <script src="/wp-content/themes/%ThemeName%/dist/runtime.js" defer></script>
    <script src="/wp-content/themes/%ThemeName%/dist/polyfills.js" defer></script>
    <script src="/wp-content/themes/%ThemeName%/dist/scripts.js" defer></script>
    <script src="/wp-content/themes/%ThemeName%/dist/main.js" defer></script>
  </body>
</html>

As you can see we replaced some parts with WordPress functions, like language_attributes, bloginfo('charset'), body_class.

Ok. The only problem, is that WordPress is not always loading index.php, sometimes it will load front-page.php, 404.php etc. So we need to force the WordPress to always load index.php. We can do that by adding this to function.php file of the WordPress theme:

add_filter('template_include', function ($template) {
    $template = get_query_template('index');
    return $template;
});

Now all we need to do is put /dist folder right along with index.php file in the theme. And it works!

If you want to compile angular on the server

Let's create angular folder in our theme and put in there all our angular files. If we run ng build --prod it would compile all files and put/dist inside the angular folder, but we need to put it outside so it's accessible with path /wp-content/themes/%ThemeName%/dist/. For that we need to add one more setting to angular.json:

...
"outputPath": "../dist",
...

Brilliant! Our compiled /dist folder will be placed outside of current (angular) folder and will be accessible for our index.php file!

I just described how I got this whole thing to work, hope it helps somebody else.

Upvotes: 4

Ikhlak S.
Ikhlak S.

Reputation: 9034

Wordpress apps should not work along with another frontend framework. Both wordpress and angular should be installed separately on different domains(sub-domains).

What you should be doing then is pulling data from your wordpress installation using Wordpress REST api and present the posts etc. with Angular or any other framework.

Upvotes: 1

Related Questions